Card filter

6th March 2021 at 2:00am
INDEX

Code Samples

25th December 2020 at 10:51pm
INDEX

AndroidChromeBrowser

25th December 2020 at 10:51pm
DOC

AndroidChromeBrowser\Desktop Shortcut to Website

8th January 2021 at 11:19am
AndroidOS Browser FileSystem

This does not work for file:///sdcard HTML files
Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Google Chrome app]
- [Non-incognito mode]
- Navigate to website page
- Note: This does not work for file:///sdcard HTML files
- [Top-right icons]
- Click the three-lines menu, option Add to Home screen -> Opens dialog
- [Add to Home screen dialog]
- Shortcut name / UrShortcutName
- Click button Add -> Closes dialog

[Desktop icons]
- Click icon UrShortcutName -> Opens browser

AndroidGit

25th December 2020 at 10:51pm
DOC

AndroidGit\Pocket Git pull repository updates

8th January 2021 at 11:19am
AndroidOS FileSystem GitCode UserAction

[Pocket Git app]
- [Repositories List page, Top-right icons]
- Click button Preferences (looks like three lines) -Navigates page
- [Preferences page, Defaults section]
- Click link Default Directory -> Opens dialog
- [Select Folder dialog]
- Select the Downloads folder -> Closes dialog
- [Preferences page, Defaults section]
- Note: Default Directory = /storage/emulated/0/Download
- Click button Back (looks like a left arrow) -> Navigates page

- [Repositories List page, Bottom-right icons]
- Click button Create Project (looks like a red button with a Plus sign) -> Opens dialog
- [Create Project dialog]
- Project Name = UrProjectName
- Clone URL = UrRepositoryURL
- Note: Local Path automatically creates a sub-directory under the Downloads folder
- Click the Authentication drop-list, option Password
- Username = UrRepositoryUsername
- Password = UrRepositoryPassword
- [Create Project dialog, Top-right icons]
- Click button Save (looks like a floppy disk) -> Closes dialog

- [Repositories List page]
- Click repository UrProjectName -> Navigates page

- [Repository page, Top-right icons]
- Click the Remotes menu (looks like a cloud), click option Fetch -> Starts process
- Wait for popup message "Finished fetching"
- Click the Remotes menu, click option Pull -> Starts process
- Wait for popup message "Finished pulling"

[File system]
- [Downloads folder]
- Note: All the files in the repository are available under the UrProjectName sub-folder in the Downloads folder

AndroidMultipleUsers

25th December 2020 at 10:51pm
DOC

AndroidMultipleUsers\Common access files

8th January 2021 at 11:19am
AndroidOS FileSystem UserAction

When you change users on an Android device, the file:///sdcard/ folder is aliased to a different location for each. There is a specific sub-folder that is aliased to the same location for all users.

[File Manager]
- Navigate to /sdcard/Android/obb
- Create a folder and copy files into it

[Android Notices menu]
- Change the current user

[File Manager]
- Navigate to /sdcard/Android/obb
- You can see the same folder and files from the other login

AndroidProgramming

25th December 2020 at 10:51pm
DOC

AndroidProgramming\DCoder

8th January 2021 at 11:18am
AndroidOS FileSystem VBCode

Note: I found that the DCoder app actually submitted the VB code to a web server. So there was no way for me to access the local file system.

  'Visual Basic.Net Compiler version 0.0.0.5943 (Mono 4.0.1)

Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Namespace Dcoder
  Public Module Program
    Public Sub Main(args() As string)
      Dim strRET = "Hi"
      For Each strENTRY As String In SubDir_List("/")
          For Each strE2 As String In SubDir_List("/" & strENTRY)
          For Each strE3 As String In SubDir_List("/" & strENTRY)
              strRET &= vbLf & strENTRY & "/" & strE2 & "/" & strE3
          Next strE3
          Next strE2
      Next strENTRY
      
      strRET &= vbLf & "Done"
      Console.WriteLine(strRET)
    End Sub 'Main

    Public Function t1(ur_root_dir As String) As String
        Return "no"
    End Function

    Public Function SubDir_List(ur_root_dir As String) As System.Collections.Generic.List(Of String)
      Dim lstRET = New System.Collections.Generic.List(Of String)
      SubDir_List = lstRET
      Try
      Dim proc = New System.Diagnostics.Process
      Dim stg = new System.Diagnostics.ProcessStartInfo
      proc.StartInfo = stg
      stg.FileName = "ls"
      stg.Arguments = ur_root_dir

      'stg.FileName = "find"
      'stg.Arguments = ". -name '*' -print"

      stg.UseShellExecute = false
      stg.RedirectStandardOutput= true
      stg.RedirectStandardError = true
      stg.CreateNoWindow = true
      proc.Start()
      Dim strCL_OUT = proc.StandardOutput.ReadToEnd()
      'strRET = "[Output: " & vbLf & strCL_OUT & "]"
      'strRET &= vbLf & "(err: " & vbLf & proc.StandardError.ReadToEnd() & ")"
      For Each strENTRY As String In strCL_OUT.Split(CHR(10))
          If strENTRY <> "" Then
              lstRET.Add(strENTRY)
          End If
      Next strENTRY
      Catch ex As System.Exception
      End Try
    End Function 'SubDir_List
  End Module
End Namespace

AndroidQLua

25th December 2020 at 10:51pm
DOC

AndroidQLua\Console Commands

8th January 2021 at 11:18am
AndroidOS CodeLibrary LuaCode

[QLua app]
- Click button Console -> Navigates page

- [console window]
- Note: The right-arrow symbol (greater-than sign) is the Lua prompt
- Note: Comment line-endings in a Lua file are separated by two hyhpens

--Single-line comment
ur_object.ur_function() --Comment until end of line

- Note: Multi-line comments in a Lua file are separated by two hyphens and two open brackets, and closed by two hyphens and two close brackets

--[[
Block comment
multiple lines
--]]

- Note: Commands in Lua are case sensitive
- - You can create functions named abc, Abc, abC, and ABC, and each one can store to a different value

- Note: Exiting the Lua interpreter returns to the Linux Shell command line interpreter that was created by QLua
- Run the os.exit() command

os.exit()

[Linux Shell CLI]
- Note: The $ symbol (dollar sign) is the Linux Shell prompt
- Note: Commands in Linux Shell are case sensitive
- - You can create programs named abc, Abc, abC, and ABC, and each one can run different code
- - Most standard Linux Shell commands are named with all lowercase characters, so only abc would be the standard way to name a program

- Note: Exiting the Linux Shell returns to the QLua app main page
- Run the exit command

exit

AndroidQLua\Console Run a Program

8th January 2021 at 11:18am
AndroidOS LuaCode UserAction

[Lua console]
- Note: I had problems using the LoadString function with the loadfile command
- - In the Lua code, replace any references to the LoadString function with the Load function
- - The Load command did not need extra escaping like\\r for the parameter, so replace \\r with \r when using the Load command
- Save the result of the loadfile command to create a new function from the file

urfile_fn=loadfile('/sdcard/qlua5/ur_file.lua')

- Note: This added a row to the _G table
- Note: Just typing a function name or a table name shows the type of data stored in the row

_G.urfile

- Output is function: 0x#####
- Note: any command except _G is an implied name lookup in the _G table

urfile

- Output is also the same function: 0x####
- Note: You can run a function by adding parentheses to the end of the function name
- Running a function can load additional functions into the _G table

urfile()

- Output is the Lua program output
- Note: Any functions or tables added to the _G table are available
- Note: You can load a Lua function and run it on the same line instead of storing the program in a variable by adding an extra pair of parentheses

loadfile('/sdcard/qlua5/ur_file.lua')()

- Output is the Lua program output

AndroidQLua\Deploy a Program Module

8th January 2021 at 11:17am
AndroidOS FileSystem LuaCode

Note: The share/5.3 directory under the QLua5 folder is where Lua looks to load "program modules" that must be loaded to the _G array as a prerequisites to running the current program

[QLua Editor]
- Note: I had problems using the LoadString function with the require command
- - In the Lua code, replace any references to the Load function with the LoadString function
- - The LoadString command needs extra escaping like\\r for the parameter, so replace \r with \\r when using the LoadString command

- [Bottom bar]
- Click button Save-As (Looks like a page with a Plus in the bottom-right corner) -> Open dialog

- [Save As dialog]
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = share
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder share
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = 5.3
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder 5.3
- [Bottom bar]
- File name = UrFileName.lua
- Click button OK (looks like a checkmark)

[File Manager]
- Note: Your Lua program is stored in folder /sdcard/qlua/share/5.3

[Lua console]
- Note: The require command to loads and runs a program module
- - Do not include the path or the .lua file extension

require 'UrFileName'

- Output is the Lua program output

AndroidQLua\Editor Run a Program

8th January 2021 at 11:17am
AndroidOS LuaCode UserAction

[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icon]
- Click button Open file (looks like a Tabbed folder) -> Opens dialog
- Select file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Note: You can change the source code and save again before each run

- [Bottom bar icons]
- Click button Run (looks like a right-arrow play button) -> Navigates page

- [console window]
- Note: The top line shows the current path and the Linux shell command used to show the editor
- Note: The output of your program is below the first line
- Note: The the last line says "Press enter to exit"

AndroidQLua\MxClasses Design

8th January 2021 at 11:17am
AndroidOS AssignVariable FileSystem LuaCode

I created some default functions that I need to see the key/value pairs in Lua tables

[def.lua]
- [def_tcompile]
- This creates a 'tcompile' function that concatenates a table's string values then loads the result as a new function
- [def_ti]
- This creates a 'ti' function that adds a new numbered row to a table
- [def_tia]
- This clears out a global table variable and creates a 'tia' function that calls the 'ti' function for that table without having to pass it in as a parameter
- [def_printk]
- This creates a 'printk' function that prints all the keys in a table, sorted alphabetically
- [def_printv]
- This creates a 'printv' function that prints all the values in a table, sorted alphabetically
- [def_tcopy]
- This creates a 'tcopy' function that copies all records from one table into another
- [def_printiv]
- This creates a 'printiv' function that prints all the values in a table, in their original order (good for numeric-keyed tables)
- [def_printkv]
- This creates a 'printkv' function that prints all keys and values in a table, sorted by key alphabetically
- [def_ioexec]
- This creates a 'ioexec' function that runs a shell command and returns a table you can store
- Example: Prints all the .lua files under a directory

local ttbFILE = ioexec('find /sdcard/qlua5 -name "*.lua" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)

- [def_printio] - This creates a 'printio' function that runs printiv on the ioexec table - Example: printio('ls /storage')

AndroidQLua\MxClasses LoadFile

8th January 2021 at 11:16am
AndroidOS CodeLibrary FileSystem LuaCode
--[under folder /sdcard/qlua5]
--This file can be run by the QLua command "LoadFile" because it uses the Load function instead of the LoadString function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) load(table.concat(ur_table, "\\r"))() end'}
load(table.concat(def_tcompile, "\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  load(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)

AndroidQLua\MxClasses Require Program Module

8th January 2021 at 11:16am
AndroidOS CodeLibrary LuaCode
--[under folder /sdcard/qlua5]
--Create subdir share/5.3
--Put in a copy of def.lua
--This file can be run by the QLua command "require" because it uses the LoadString function instead of the Load function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) loadstring(table.concat(ur_table, "\\r"))() end'}
loadstring(table.concat(def_tcompile, "\\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  loadstring(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
--[[
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)
--]]

AndroidQLua\Source Code Editor

8th January 2021 at 11:16am
AndroidOS LuaCode UserAction

[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icons]
- Click button New File (looks like a page with a Plus sign) -> Opens dialog

- [New file dialog]
- Click option Blank file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Enter some text

- [Bottom bar]
- Click button Save (looks like a 3.5" floppy disk)

[SDCard file list]
- Note: The file gets saved in the folder /sdcard/qlua5

AndroidScreenshot

25th December 2020 at 10:51pm
DOC

AndroidScreenshot\Screenshot Easy

8th January 2021 at 11:15am
AndroidOS Extract Video

[Google Play Store app]
- Install app Screenshot Easy by Ice Cold Apps
- Note: Contains ads

AndroidVNC

25th December 2020 at 10:51pm
DOC

AndroidVNC\RealVNC remote control Windows O/S

8th January 2021 at 11:15am
AndroidOS UserAction Video WindowsOS

Windows O/S

[https://www.realvnc.com/en/connect/download/viewer/windows/]
- Install app VNC Connect for Windows

[VNC Connect for Windows app]
- Connects to login
- Note: Allows connection by RealVNC's VNC Viewer app on Android O/S

Android O/S

[Google Play Store]
- Install app VNC Viewer by RealVNC Limited

[VNC Viewer app]
- Connects to login
- [Alt tab]
- Use Ctrl-Esc to get to the Windows Start Menu and the Task Bar to change windows

AndroidVNC\Remote Control Android Device

8th January 2021 at 11:14am
AndroidOS UserAction Video

Install app AnyDesk by AnyDesk Software GmbH
- https://play.google.com/store/apps/details?id=com.anydesk.anydeskandroid&hl=en_US&gl=US

Install on both Android devices
- The other installed devices will show when connected to the same WiFi network
- Automatically figures out how to use the controlling Android device's touch screen

AndroidWebDav

25th December 2020 at 10:51pm
DOC

AndroidWebDav\BestDAV

8th January 2021 at 11:14am
AndroidOS FileSystem UserAction

Access files on Android device from a networked Windows computer

[Andrdoid OS]
- [Google Play Store]
- Install app WebDAV Server - BestDAV
- - Free or Pro edition

[WebDAV Server]
- [Main page, top bar]
- Note: Folders not listed under the "Folders" button automatically has read-only access via WebDav
- Click button Settings -> nav
- [Settings page]
- Website Home Directory = /storage
- [Main page, bottom bar]
- Click button Start Server
- Note: The server's network URL starts with "http://" and ends with ":8080"
- - Sample = http://192.168.0.15:8080

[Windows computer]
- [browser]
- Address = http://192.168.0.15:8080
- Click link Get the file list -> nav
- Note: The directory shows the "external" SD Card name (if any) and "enc_emulated"
- To see the "internal" /sdcard folder on the android device,
- - Click link "enc_emulated" -> /_dir.cgi?dir=%2Fenc_emulated
- - Edit the address to say /_dir.cgi?dir=%2Femulated/0

- [Windows Explorer]
- Address = \\192.168.0.15@8080\DavWWWRoot
- Note: The directory shows the "external" SD Card name (if any) and "emulated", "enc_emulated", and "self"
- To see the "internal" /sdcard folder on the android device,
- - Click link "emulated" -> http://192.168.0.15:8080/emulated
- - Edit the address to say http://192.168.0.15:8080/emulated/0

btn Delete Cards

6th March 2021 at 8:01pm
$:/positivesigner/base-install

ChromeBrowser

25th December 2020 at 10:51pm
DOC

ChromeBrowser\Browse Local Folders

8th January 2021 at 11:14am
Browser Extract FileSystem

Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome

[Google Chrome app]
- [Windows O/S]
- Navigate to file:///C:/
- [Android O/S]
- Navigate to file:///sdcard/

- [Directory list]
- Select which sub-folder you want to bookmark
- [Navigation bar, Top-right icons]
- Click button Bookmark Page (looks like a star shape) -> Opens dialog
- [Bookmark Added dialog]
- Name = UrShortName
- Click button Done -> Closes dialog
- [Navigation bar]
- Address = UrShortName -> Shows suggestions
- [Suggestion list]
- Select the suggested link -> Navigates page

ChromeBrowser\Command Line Options

8th January 2021 at 11:13am
AssignVariable Browser CodeLibrary

The command line options are usually two hyphens followed by a keyword

- Note: The incognito option starts the browser with an open Incognito window

–incognito

- Note: Google Chrome Portable has these parameters automatically included when calling the Chrome.exe program.

–user-data-dir="%TEMP%"
–disk-cache-dir="%TEMP%\GoogleChromePortable\Cache"

To override the user data and all the cache directories:

- Find the INI file in the PortableApp sub-directory

GoogleChromePortable\Other\Source\GoogleChromePortable.ini

- Copy it to the program main directory

GoogleChromePortable\GoogleChromePortable.ini

- [Edit the file]
- CacheInTemp = false
- Save file
- Note: When you restart Google Chrome Portable, cached files will be stored under the program's folder

C:\TJBF\zPortableInstalls\Chrome\Data\profile\Default\*Cache\

ChromeBrowser\Turn off Chrome spell check highlighting

8th January 2021 at 11:13am
Browser CodeLibrary Formatting Text

[Google Chrome app]
- [Top-right icons]
- Click the three-dots menu, option Settings -> Navigates page
- [Settings page[
- search for Language -> Filters results
- [Languages section]
- checkbox Spell check = clear -> Chrome will not highlight spelling errors

DivPop btn

6th March 2021 at 8:58pm
$:/positivesigner/div-pop $:/tags/ViewToolbar

DivPop glbl

6th March 2021 at 8:58pm
$:/positivesigner/div-pop $:/tags/BelowStory

Excel VBA

25th December 2020 at 10:51pm
DOC

Excel VBA\Get Worksheet

8th January 2021 at 11:12am
CodeLibrary ExcelCode FileSystem
Dim wksDATA As Worksheet
Set wksDATA = Application.ActiveSheet
wksDATA.Cells(2,2).Value = "Hi"

'Press F5 to run the macro
'Note: Cell B2 says "Hi"

Excel VBA\New Macro

8th January 2021 at 11:12am
AssignVariable ExcelCode FileSystem

[Microsoft Excel application]
- [Ribbon menus]
- View menu, option Record Macro -> Starts recording
- View menu, option Stop Recording -> Stops recording
- View menu, option Macros -> Opens dialog

[Macro list]
- Click button Edit Macro -> Opens window

[VBA Editor]
- You can change the name of the macro and add commands
- Close the editor

[Microsoft Excel application]
- Save the file as a Macro-Enabled workbook (mwb)

Excel VBA\Power Exponent

8th January 2021 at 11:12am
ExcelCode Extract Numbers

Make sure you put a space between the power operator (^) and the numbers

- CalcResult = 2^5
- Note: This gives a compilation error on 64-bit Excel

- CalcResult = 2 ^ 5
- Note: CalcResult = 32

ext TW Return

6th March 2021 at 8:02pm
$:/positivesigner/text-ref

FFMPeg

25th December 2020 at 10:51pm
DOC

FFMPeg\Extract Captions file

8th January 2021 at 11:11am
Extract Text WindowsOS
chcp 65001
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" "C:\UrPath\UrFile.srt"
pause

FFMPeg\Extract JPG files

8th January 2021 at 11:11am
Extract Video WindowsOS

[ffmpeg.exe command-line options]
- -ss 05:00 -t 10:00 means start at 5min and end 10min later at 15min
- -r 1 means 1 frame per second
- -r 0.25 means 1 frame every 4 seconds
- -r 0.083 means 1 frame every 12 seconds, or 5 frames per minute, 50 frames out of every ten minutes, or 300 frames every hour

- IrfanView can create a portrait contact sheet with 5 columns, representing one min of video per row, 10 rows per page showing 10 minutes of video
- IrfanView can create a landscape contact sheet with 7 columns is one 3 min per 2 rows, 7 rows per page showing 10.5 minutes of video, two pages showing 21 minutes

- Open on thumbnail image with IrfanView, select File menu Thumbnails option
- Select all files in the folder, select File menu Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

chcp 65001
rem -ss 05:00 -t 10:00 means start at 5min and end 10min later at 15min
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" -r 0.083 -s 320x180 "UrPath\UrSubdir\output_%%04d.jpg"

Font Size

6th March 2021 at 8:40pm
$:/positivesigner/text-ref

Specific prefix filter: 334 cards

Non-system plus system PositiveSigner filter: 334 cards



Panel

Cards where has[tags] does not work

Cards with no tags

parm SkipSaveExportHTML

btn Delete Cards

GitCLI

25th December 2020 at 10:51pm
DOC

GitCLI\Checkout hash

8th January 2021 at 11:09am
Extract FileSystem GitCode
@echo off
SET ur_repo=
SET ur_branch=
"C:\UrPath\git.exe" -C %ur_repo% checkout -b test-branch %ur_branch%

rem Use GitHub Desktop to delete the branch

GitHubDesktop

25th December 2020 at 10:51pm
DOC

GitHubDesktop\Git executable

8th January 2021 at 11:10am
FileSystem GitCode WindowsOS

When GitHub Desktop is installed, the Git.exe program is placed in the %APPDATA% folder. There is one sub-directory for each version of Git that has been downloaded. Look for the latest version-numbered folder.

C:\Users\UrUser\AppData\Local\GitHubDesktop\app-UrVersion

Under the app-UrVersion folder, find the Git.exe program

app-UrVersion\resources\app\git\cmd\git.exe

GoogleContacts

25th December 2020 at 10:51pm
DOC

GoogleContacts\Export as CSV

8th January 2021 at 11:08am
Extract FileSystem Service

[https://contacts.google.com/]
- [Left-side menu]
- Click button Export -> Opens dialog
- Export contacts = Contacts (total count)
- Export as = Google CSV
- Click button Export -> Downloads file, Closes dialog

[CSV file]
- Header fields =

Name
Given Name
Additional Name
Family Name
Yomi Name
Given Name Yomi
Additional Name Yomi
Family Name Yomi
Name Prefix
Name Suffix
Initials
Nickname
Short Name
Maiden Name
Birthday
Gender
Location
Billing Information
Directory Server
Mileage
Occupation
Hobby
Sensitivity
Priority
Subject
Notes
Language
Photo
Group Membership
E-mail 1 - Type
E-mail 1 - Value
E-mail 2 - Type
E-mail 2 - Value
Phone 1 - Type
Phone 1 - Value
Phone 2 - Type
Phone 2 - Value
Address 1 - Type
Address 1 - Formatted
Address 1 - Street
Address 1 - City
Address 1 - PO Box
Address 1 - Region
Address 1 - Postal Code
Address 1 - Country
Address 1 - Extended Address
Organization 1 - Type
Organization 1 - Name
Organization 1 - Yomi Name
Organization 1 - Title
Organization 1 - Department
Organization 1 - Symbol
Organization 1 - Location
Organization 1 - Job Description
Relation 1 - Type
Relation 1 - Value
Website 1 - Type
Website 1 - Value

- Header line =

Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initials,Nickname,Short Name,Maiden Name,Birthday,Gender,Location,Billing Information,Directory Server,Mileage,Occupation,Hobby,Sensitivity,Priority,Subject,Notes,Language,Photo,Group Membership,E-mail 1 - Type,E-mail 1 - Value,E-mail 2 - Type,E-mail 2 - Value,Phone 1 - Type,Phone 1 - Value,Phone 2 - Type,Phone 2 - Value,Address 1 - Type,Address 1 - Formatted,Address 1 - Street,Address 1 - City,Address 1 - PO Box,Address 1 - Region,Address 1 - Postal Code,Address 1 - Country,Address 1 - Extended Address,Organization 1 - Type,Organization 1 - Name,Organization 1 - Yomi Name,Organization 1 - Title,Organization 1 - Department,Organization 1 - Symbol,Organization 1 - Location,Organization 1 - Job Description,Relation 1 - Type,Relation 1 - Value,Website 1 - Type,Website 1 - Value

- Sample data 1

.me,.me,,,,,,,,,,,,,,,,,,,,,,,,,,,Imported 8/5/16 ::: * myContacts,,,,,Mobile,5554443333 ::: 16665554444,,,,,,,,,,,,,,,,,,,,,,,

- Sample data 2

UrContactName,UrContactFirstName,,UrContactLastName,,,,,,,,,,,,,,,,,,,,,,,,,* myContacts,,,,,Mobile,(444) 333-2222,,,,,,,,,,,,,,,,,,,,,,,

GoogleGmail

25th December 2020 at 10:51pm
DOC

GoogleGmail\Export as MBOX

8th January 2021 at 11:07am
Extract FileSystem Service

[https://takeout.google.com/]
- [Products section]
- Click link Deselect All
- [Mail section]
- checkbox = set
- [End of Page section]
- Click button Next Step -> Navigates section
- [Choose file type, frequency & destination]
- Frequency = Export once
- File type = .zip
- File size = 2 GB
- Click button Create Export -> Navigates section
- [Export Progress]
- Note: Google is creating a copy of files from Mail. This process can take a long time (possibly hours or days) to complete. You'll receive an email when your export is done.

[https://mail.google.com/]
- [Message with title "Archive of Google data requested"]
- Note: You can ignore the message or click the link to verify it was you
- [Message with title "Your Google data is ready to download"]
- Click button Download Your Files -> Opens tab

[Google Takeout form]
- Re-enter your password
- [Record where Export = Mail]
- Note: The size of the export file is also in the Export column
- Click button Download -> Downloads file
- Note: The file may take a long time to download depending on your internet connection and the size of the file

[ZIP file]
- Extract the ZIP file to a folder

[Takeout folder]
- Open the archive_browser.html -> Opens browser

[Archive Browser page]
- [File Formats tab]
- Note: An mbox is a way of storing mail messages and is supported by common mail clients like Microsoft Outlook, Mozilla Thunderbird, and Apple's Mail program. These files are most easily opened by a dedicated mail client like those listed above

[Takeout\Mail folder]
- [All mail Including Spam and Trash.mbox]
- Use Mozilla Thunderbird to read the MBOX file
- OR Split this file into smaller text files... somehow
- Format:

Record Start = Leading "From " <- Including the space
Tags = "WordsWithoutSpaces:" <- no spaces in tag name
Tag continuation values = " Every Line With Leading Space Or Tab After Tag Name"
Email Content = "First line that is not a tag or tag continuation -> through last line before next leading " "From "

GoogleGmail\MBOX file parsing test

8th January 2021 at 11:07am
Extract Service Text
start "" "%~dp0\MxClasses\VBNetScript.exe" /path=%0 & exit
MxClasses\MxBaseEc12.vb
RetVal = Mx.Want.TextFile_Split_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.TextFile_Split_errhnd
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub TextFile_Split(ret_message As Strap)
			Dim tabchr = CHR(9)
			Dim flnDATA = FileNamed().d("C:\Users\Dad\Downloads\Takeout\Mail\All mail Including Spam and Trash.mbox")
			Dim intLINE_COUNT = 0
			Dim sdaPREFIX_SKIPPED = New Sdata
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), False, gUTF8_FileEncoding)
				Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
				    Dim bolINCLUDE_INDENTED_LINES = False
					Dim bolHTML_TEXT = False
					Dim bolPLAIN_TEXT = False
					Dim bolSKIP_TEXT = False
					While stmDATA.EndOfStream = False
						Dim strLINE = stmDATA.ReadLine()
						If strLINE.Length = 0 Then
						
						ElseIf Left(strLINE, 5) = "From " AndAlso
						  Len(strLINE) = 59 Then
						    bolINCLUDE_INDENTED_LINES = False
							bolHTML_TEXT = False
							bolPLAIN_TEXT = False
							bolSKIP_TEXT = False
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine(strLINE)
							intLINE_COUNT += 1
						
						ElseIf bolSKIP_TEXT Then
						
						ElseIf bolPLAIN_TEXT Then
							If strLINE.Trim.Length > 0 Then
								Dim bolCUR_HTML = False
								Dim intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									bolCUR_HTML = True
									
									End If
								
								If Left(strLINE, 16) = "X-Attachment-Id:" OrElse
								  Left(strLINE, 32) = "Content-Transfer-Encoding:base64" Then
									bolSKIP_TEXT = True
									
									End If 'strLINE
								
								If bolHTML_TEXT = False Then
									stmOUT_FILE.WriteLine(strLINE)
									intLINE_COUNT += 1
								
								ElseIf bolCUR_HTML Then
									Dim strTEXT = strLINE
									While intFOUND_SPRTR > 0
										Dim strPREFIX = Mid(strTEXT, 1, intFOUND_SPRTR - 1)
										Dim strTAG = Mid(strTEXT, intFOUND_SPRTR)
										intFOUND_SPRTR = InStr(strTAG, ">")
										If intFOUND_SPRTR = 0 Then
											strTEXT = strPREFIX
										
										Else
											strTEXT = strPREFIX & Mid(strTAG, intFOUND_SPRTR + 1)
											intFOUND_SPRTR = InStr(strTEXT, "<")
											
											End If 'intFOUND_SPRTR
										
										End While 'intFOUND_SPRTR
									
									If strTEXT.Trim.Length > 0 Then
										stmOUT_FILE.WriteLine(strTEXT)
										intLINE_COUNT += 1
										
										End If
									
									End If 'intFOUND_SPRTR
									
								End If 'strLINE
							
						ElseIf (Left(strLINE, 1) = s OrElse Left(strLINE, 1) = tabchr) AndAlso
						  bolINCLUDE_INDENTED_LINES Then
							'stmOUT_FILE.WriteLine(strLINE)
							'intLINE_COUNT += 1
						    
						Else 'strLINE
						    bolINCLUDE_INDENTED_LINES = False
							Dim strPREFIX = mt
						    Dim intFOUND_SPRTR = InStr(strLINE, ":")
							If intFOUND_SPRTR > 0 Then
							    strPREFIX = Mid(strLINE, 1, intFOUND_SPRTR)
								If InStr(strPREFIX, tabchr) > 0 OrElse
								  InStr(strPREFIX, s) > 0 Then
									strPREFIX = mt
									
									End If
								
								End If
							
							If strPREFIX = "Content-Type:" OrElse
							  strPREFIX = "Subject:" OrElse
							  strPREFIX = "To:" OrElse
							  strPREFIX = "Date:" OrElse
							  strPREFIX = "From:" Then
								bolINCLUDE_INDENTED_LINES = True
								stmOUT_FILE.WriteLine(strLINE)
								intLINE_COUNT += 1
							
							ElseIf Right(strPREFIX, 1) = ":" Then
								bolINCLUDE_INDENTED_LINES = True
								If sdaPREFIX_SKIPPED.Contains(strPREFIX) = False Then
									sdaPREFIX_SKIPPED.d(strPREFIX)
									
								    End If
							
							ElseIf strPREFIX = "" Then
							    bolPLAIN_TEXT = True
								intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									
									End If
								
								End If 'strPREFIX
							
							End If 'strLINE
						
						If intLINE_COUNT >= 100000 Then
							Exit While
							
							End If
						
						End While 'stmDATA
					
					End Using 'stmDATA
				
				End Using 'stmOUT_FILE
			
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("PREFIX_SKIPPED.TXT"), False, gUTF8_FileEncoding)
				Call sdaPREFIX_SKIPPED.Sort()
				For Each strENTRY In sdaPREFIX_SKIPPED
					stmOUT_FILE.WriteLine(strENTRY)
					
					Next strENTRY
				
				End Using 'stmOUT_FILE

			ret_message.Clear.d(intLINE_COUNT.ToString)
			
			End Sub 'TextFile_Split

        Public Shared Function TextFile_Split_errhnd() As Strap
            Dim stpRET = Strapd()
            TextFile_Split_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call TextFile_Split(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'TextFile_Split_errhnd
    End Class 'Want
End Namespace 'Mx

GooglePlay

25th December 2020 at 10:51pm
DOC

GooglePlay\Share purchased apps with another account

8th January 2021 at 11:07am
FileSystem Service UserAction

[Play Store app]
- [Top-left icon]
- Click the three-lines menu, option Family Library -> Navigates page
- Note: There are two Sections
- - Added by [Other]
- - Added by you

If the purchased app you want to share is not shown under the Added by You section, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option My apps & games -> Navigates page
- [Installed tab, or Library tab]
- Choose an app you purchased -> Navigates page
- [App page]
- Note: The checkbox Family Library is a toggle switch
- checkbox Family Library = set -> The app is available to all Family logins

If the 'Family' logins does not contain the account you want to access your shared app, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option Account -> Navigates page
- [Family tab]
- Click button Manage family members -> Opens dialog
- [Family dialog]
- Click button Invite family members -> Opens dialog
- [Verify CVC dialog]
- Enter your credit card number's CVC number
- Click button Verify -> Closes dialog, Opens dialog
- [Send Invitations dialog]
- Select a contact
- Click button Send

[Added Account email]
- Click the invitation link -> Navigates page
- Note: The Added Account can now use the Play Store app to install the Family Library shared app

GooglePlusCodes

25th December 2020 at 10:51pm
DOC

GooglePlusCodes\Find a Plus Code

8th January 2021 at 11:06am
Extract FileSystem Numbers Service

[https://plus.codes/map/]
- [Search box, Left-side icon]
- Click the three-lines menu, option Satellite -> Refreshes window
- Click the three-lines menu, option Grid -> Refreshes window
- [Navigate to location]
- When the mouse icon is a hand, double-click to Zoom in
- Each time you click, the location will show as 8 characters, a plus sign, and two suffix characters
- - Example: 73F6C9JH+HR
- The last two Zoom levels allow you to select a single Plus Code rectangle, which has three suffix characters after the plus sign
- - Example: 73F6C9JH+HR7
- Copy the browser address bar
- - Example: https://plus.codes/73F6C9JH+HR7

- Note: You can email the page link to someone
- - They will have to turn on the satellite and / or grid options again

- Note: You can use the browser to bookmark the current page
- - Android O/S Chrome can create a desktop shortcut to the current website page (when not in Incognito mode)

- Note: The plus codes are 8 characters, a plus, and two or three suffix characters
- - The bottom of the Plus.Codes website's map only temporarily shows the three suffix characters after you click, quickly reverting to show only two suffix characters
- - You can still see all three suffix characters in the address bar

- [Bottom location code bar, Right-side icon]
- Click button Navigate (looks like a Right-Turn Only road sign) -> Navigates to Google Maps website
- Note: Android O/S Chrome app will ask to Stay On Web or Use The App
- - Click button Use The App to open the Google Maps app

HTML CSS

25th December 2020 at 10:51pm
DOC

HTML CSS\Comment Declaration

9th January 2021 at 9:37am
HTMLCode Text

HTML 5 document

  • Declaration Name = --
  • Content = unprocessed text, except for the character sequence double-hyphen close-tag ( --> )
  • Note: HTML declarations are not tags, because the have an exclamation mark ( ! ) before the declaration name / code
  • Note: XML documents have a requirement that a double-hyphen ( -- ) must itself be doubled ( ---- ) when used in a comment declaration, but HTML 5 has no such requirement

Sample code for HTML 5 Comment

<!-- a text editor can see the comment text -->

HTML CSS\Comment MOTW Declaration

9th January 2021 at 9:49am
Browser HTMLCode Text

HTML document viewed in Internet Explorer

  • Comment text sequence:
  • <!-- and optional whitespace
  • saved from url=(
  • the number of characters in the URL string (including the trailing backslash)
  • )
  • the URL string
  • optional whitespace and -->
  • HTML documents viewed in Internet Explorer show a warning message due to active content, or has a specifically crafted HTML Comment Declaration that names the root URL of the website it is being hosted on
  • Note: If this is for a new site, or if the domain is not known, you can use about:internet as a valid URL

JTFAssociates MOTW

->

Sample code

<!-- saved from url=(0014)about:internet -->

HTML CSS\Compatibility Meta tags

10th January 2021 at 4:10pm
Browser Formatting HTMLCode

Declare compatibility version of Microsoft Internet Explorer web browser

  • tag name = meta
  • http-equiv attr = X-UA-Compatible
  • content attr = IE=Edge or (IE=11, IE=EmulateIE11, and similar version number pairs)
  • Note: Use this tag if you need features specific to an older version of IE like IE9 or IE8
  • Note: If you only support the latest browsers (IE11 and/or Edge) then this tag will not affect the web page's behavior until another version is created

Internet Explorer begins interpreting markup using the latest version. When Internet Explorer encounters the X-UA-Compatible META tag it starts over using the designated version's engine. This is a performance hit because the browser must stop and restart analyzing the content.

StackOverflow Meta UA-Compatible

->

Sample code

<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>

content="IE=Edge" mode tells Internet Explorer to display content in the highest mode available. With Internet Explorer 9, this is equivalent to IE9 mode. If a future release of Internet Explorer supported a higher compatibility mode, pages set to edge mode would appear in the highest mode supported by that version. Those same pages would still appear in IE9 mode when viewed with Internet Explorer 9.

Specify web application runs in full-screen mode on Apple devices

  • tag name = meta
  • name attr = apple-mobile-web-app-capable
  • content attr = yes
  • Note: The default behavior is to use Safari to display web content
  • Note: You can determine whether a webpage is displayed in full-screen mode using the window.navigator.standalone Boolean JavaScript property

Apple.com Safari Meta tags

->

Sample code

Specify the Full Screen's status bar style on Apple devices

  • tag name = meta
  • name attr = apple-mobile-web-app-status-bar-style
  • content attr = default, black, black-translucent
  • Note: If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar
  • Note: This meta tag has no effect unless you first specify full-screen mode as described in apple-apple-mobile-web-app-capable

Apple.com Safari Meta tags

->

Sample code

<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

Leave original formatting of telephone-number formatted strings

  • tag name = meta
  • name attr = format-detection
  • content attr = telephone=no
  • Note: By default, Safari on iOS detects any string formatted like a phone number and makes it a link that calls the number

Apple.com Safari Meta tags

->

Sample code

<meta name="format-detection" content="telephone=no" />

Specify web application runs in full-screen mode on Apple devices

  • tag name = meta
  • name attr = mobile-web-app-capable
  • content = yes
  • Note: This tells the browser to launch the page fullscreen when the user has added it to the home screen
  • Note: A better option is to use the Web App Manifest for Chrome, Opera, Firefox, and Samsung browsers

GoogleDevelopers FullScreen web app

->

Sample code

<meta name="mobile-web-app-capable" content="yes"/>

HTML CSS\CSS Style definitions

10th January 2021 at 5:11pm
Browser CSSCode FileSystem

Place a CSS style-sheet in the HTML document

  • tag name = style
  • type attr = text/css
  • Note: The most recent versions of the HTML spec now permits the <style> tag within body elements
  • Note: Putting CSS in body means it is loaded later and the browser starts drawing the interface faster
  • Note: Putting CSS in body can decrease page performance due to possible reflows/repaints once the browser hits styles further down in the page tree

StackOverflow CSS location

->

Sample code

<style type="text/css">

Place a comment inside of a CSS style-sheet

  • Start CSS comment text with forward-slash asterisk ( /* )
  • End CSS comment text with asterisk forward-slash ( */ )

MozillaDeveloper CSS Comment

->

Sample code

<style type="text/css">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>

HTML CSS\Declare document Content type

9th January 2021 at 9:50am
Browser HTMLCode Text

HTML CSS\Head section

10th January 2021 at 3:12pm
Browser Formatting HTMLCode

Set metadata values for interpreting document contents

  • The <head> element is a container for metadata (data about data) and is placed between the <html> tag and the <body> tag
  • Metadata describes how to interpret and format the HTML document stored within the <body> tag

W3Schools Head tag

->

Sample code

<head>
  <title>UrTitle</title>
</head>

HTML CSS\Hide content

10th January 2021 at 5:28pm
Browser Formatting HTMLCode

Hide content until user action

  • CSS style name = display
  • value = none
  • Note: The entire tag and sub-tag structure is hidden
  • Note: To hide the root tag and show a child tag, use CSS styles visibility: hidden and visibility: visible, though the parent markup will still take up screen real estate

StackOverflow Hide Parent Show Child tag

->

HTML CSS\HTTP-EQUIV Document Type

10th January 2021 at 3:07pm
Browser FileSystem HTMLCode

Simulate an HTTP Respsonse header

  • The http-equiv attribute value content-type provides an HTTP header specifying that the character encoding for the document is in the content attribute

W3Schools Meta HTTP-EQUIV

->

Sample code

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

HTML CSS\iFrame to Local HTML file

8th January 2021 at 10:32am
Extract FileSystem HTMLCode
<iframe src="UrPath\UrFile.html" scrolling=yes style="border-style:none;height:75%;width:100%" ></iframe>

HTML CSS\Language attribute on tags

10th January 2021 at 3:46pm
Browser Formatting HTMLCode

Allow screen-reader to identify the page's default language and / or accent

  • tag name = any
  • lang attr = an ISO-639 Language code
  • The official W3C recommendation is to declare the primary language for each Web page with a <...lang => attribute in the <html> tag
  • Note: The LANG tag (i.e. the lang="" attribute) is designed to signal screen readers pronunciation engines to switch to another language or accent

PSU.edu LangTag

->

Sample code

<html lang="en-GB">

HTML CSS\META Tag names

10th January 2021 at 4:13pm
AssignVariable Browser HTMLCode

Identify tool or program used to create the website

  • tag name = META
  • name attr = generator
  • content attr = The name of the program you used to create your website
  • Note: This tag is automatically inserted by website-generating applications
  • Note :People who don’t want to advertise which tool or program they used to create the website can remove this tag from the generated pages

MetaTags.org Generator

->

Sample code

<meta name="generator" content="UrProgramTitle" />

Identifies the name of the application running in the web page

  • tag name = META
  • name attr = application-name
  • content attr = The application that is dynamically supplying content for the current web page
  • Note: isolated web pages shouldn't define an application-name

Mozilla.org META tags

->

<meta name="application-name" content="UrApplicationTitle" />

Supply hints about the size of the initial size of the viewport

  • tag name = META
  • name attr = viewport'
  • content attr = comma-separated list of equates
  • Note: This is used by mobile devices only
  • Note: The default values may vary between devices and browsers
  • Note: Disabling zooming capabilities by setting user-scalable to a value of no prevents people experiencing low vision conditions from being able to read and understand page content
  • width = ( A positive integer number ) or ( the text device-width )
  • height = ( A positive integer) or ( the text device-height )
  • initial-scale = A positive number between 0.0 and 10.0
  • maximum-scale = A positive number between 0.0 and 10.0
  • minimum-scale = A positive number between 0.0 and 10.0
  • user-scalable = yes, no
  • viewport-fit = auto', 'contain, cover

Mozilla.org META tags

->

Sample code

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

Include developer or company information in document

  • tag name = meta
  • name attr = copyright, ur_app_name-version
  • content attr = Any text data
  • Note: This information is not used by the browser

HTML CSS\Meta Tag Schema

9th January 2021 at 9:00am
AssignVariable Browser HTMLCode

W3.org HTML401 Meta

->

This specification does not define a set of legal meta data properties. The meaning of a property and the set of legal values for that property should be defined in a reference lexicon called a profile.

W3.org HTML401 Profiles

->

The profile attribute of the HEAD specifies the location of a meta data profile. The value of the profile attribute is a URI. User agents may use this URI in two ways:

  • As a globally unique name.

User agents may be able to recognize the name (without actually retrieving the profile) and perform some activity based on known conventions for that profile. For instance, search engines could provide an interface for searching through catalogs of HTML documents, where these documents all use the same profile for representing catalog entries.

  • As a link.

User agents may dereference the URI and perform some activity based on the actual definitions within the profile (e.g., authorize the usage of the profile within the current HTML document). This specification does not define formats for profiles.

HTML CSS\Padding and Margin

8th January 2021 at 11:05am
CSSCode Formatting HTMLCode
style="margin-left:30px"

style="padding-left:10px"

HTML CSS\Table Rows Alternate

8th January 2021 at 11:04am
CSSCode Formatting HTMLCode

Stylesheet classes:

.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}

HTML using class

<table class="alternating-rows">
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

HTML CSS\Website icon

10th January 2021 at 4:54pm
Browser FileSystem Formatting HTMLCode

Show an icon next to the Website Name

  • tag name = link
  • rel attr = icon, shortcut icon
  • href attr = Website icon filename, relative path, or full path
  • Note: The favicon is loaded as soon as the browsers parses the link rel="icon" declaration, or after the page is loaded when the link is not found
  • Note: The icon keyword may be preceded by the keyword "shortcut". If the "shortcut" keyword is present, the rel attribute's entire value must be an ASCII case-insensitive match for the string "shortcut icon" (with a single U+0020 SPACE character between the tokens and no other ASCII whitespace).

MathiasBynens Rel Icon

->

WHATWg.org Link Icon

->

Sample code

<link rel="shortcut icon" href="favicon.ico">

Instapaper

25th December 2020 at 10:51pm
DOC

Instapaper\Export as CSV

8th January 2021 at 11:05am
Extract FileSystem Service

[https://www.instapaper.com/u]
- [Top-right icon]
- Click login-name menu, option Settings -> Navigates page
- [Settings page, Export section]
- Click link Download .CSV file -> Opens dialog
- Click button OK -> Starts download, closes dialog

[CSV file]
- Header fields =

URL
Title
Selection
Folder
Timestamp

- Header line =

URL,Title,Selection,Folder,Timestamp

- Sample data 1 =

https://m.youtube.com/watch?v=ABC123DEF&index=14,"""UrQuotedText"" - UrVideoTitle",UrCommentText,"UrInstapaperFolder",1605840648

- Sample data 1 =

https://www.urcompany.com/urfolder/urarticle/,UrArticleTitle,,UrInstapaperFolder,UrCommentText1603883475

Instapaper\Parse file

8th January 2021 at 11:06am
Extract Service Text
\define link_title()
''[<$list filter="[<http_text>split[,]butlast[]last[]]" />]'' <$list filter="[<http_text>split[,]rest[]first[]]" />
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]floor[]]"><$vars tid_year=<<currentTiddler>> >
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]subtract<tid_year>multiply[12]floor[]]"><$vars tid_month=<<currentTiddler>> >
(<<tid_year>>-<<tid_month>>)
</$vars></$list>
</$vars></$list>
<ul>
<$list filter='[<http_text>split[,]butlast[]butlast[]butfirst[]butfirst[]join[,]split["]butfirst[]butlast[]join["]split[""]join["]split[...]]'>
<li><<currentTiddler>></li>
</$list>
</ul>
\end
<$list filter="[{WebNotes\Data}split[http]count[]]" ><$vars total_count=<<currentTiddler>> >Count of entries: <<total_count>><br><br>
<!--
<$button>
<$action-setfield $tiddler="$:/state/popup/audit_1k" text="0"/>
Reset
</$button><br>

<$button>
<$list filter="[{$:/state/popup/audit_1k}add[1000]]">
<$action-setfield $tiddler="$:/state/popup/audit_1k" text=<<currentTiddler>> />
Next 1k
</$list>
</$button><br>
{{$:/state/popup/audit_1k}}

<$list filter="[{WebNotes\Data}split[http]first{$:/state/popup/audit_1k}last[1000]]"><$vars http_text=<<currentTiddler>> >
-->
<$list filter="[{WebNotes\Data}split[{{]join[-opencurlybrace-]split[http]]"><$vars http_text=<<currentTiddler>> >
<$list filter="[<http_text>split[,]first[]!suffix[URL]addprefix[http]]"><$vars http_link=<<currentTiddler>> >
<$list filter="[all[tiddlers]field:twnote<currentTiddler>count[]match[0]]">
<<http_link>><br>
- <<link_title>> <br>
</$list>
</$vars></$list>
</$vars></$list>
</$vars></$list>

IrfanView

25th December 2020 at 10:51pm
DOC

IrfanView\Contact Sheet

8th January 2021 at 11:03am
Formatting Video WindowsOS

[IrfanView app]
- Open one thumbnail image -> Loads image
- Click the File menu option Thumbnails -> Opens dialog
- [Thumbnails dialog]
- Select all files in the folder
- Click the File menu, option Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

JavaScript

25th December 2020 at 10:51pm
DOC

JavaScript\Comment text

10th January 2021 at 7:12pm
Browser CSSCode FileSystem

Place a comment text block inside of a JavaScript program

  • tag name = script
  • type attr = text/javascript
  • Start JavaScript comment text block with forward-slash asterisk ( /* )
  • End comment text with asterisk forward-slash ( */ )
  • Start JavaScript comment text line with two forward-slashes ( // )

Sample code

<style type="text/javascript">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>

JavaScript\Execute Nameless Function

8th January 2021 at 11:03am
FileSystem JavaScriptCode UserAction
;(
    function() {
        alert('hi');
        }
    )();

JavaScript\Exports object

10th January 2021 at 9:00pm
FileSystem JavaScriptCode

Determine if running under Node.JS

  • Initially at least, exports is a reference to module.exports
  • If you assign anything to module.exports, exports is not no longer a reference to it, and exports loses all its power

SitePoint Exports Node.JS

->

JavaScript\Invalid Variable Names

8th January 2021 at 11:02am
AssignVariable ErrorHandling JavaScriptCode

JavaScript Strict Mode

->

Strict mode makes assignments which would otherwise silently fail to throw an exception. For example, NaN is a non-writable global variable. In normal code assigning to NaN does nothing; the developer receives no failure feedback. In strict mode assigning to NaN throws an exception.

'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError

Strict mode in ECMAScript 2015 forbids setting properties on primitive values. Without strict mode, setting properties is simply ignored (no-op), with strict mode, however, a TypeError is thrown.

(function() {
'use strict';

false.true = '';         // TypeError
(14).sailing = 'home';   // TypeError
'with'.you = 'far away'; // TypeError

})();

JavaScript\Labels

8th January 2021 at 11:02am
CodeLibrary FileSystem JavaScriptCode

The labeled statement can be used with break or continue statements.

List: 
while(counter < 50)
{
     userInput += userInput;
     counter++;
     if(userInput > 10000)
     {
          break List;
     }
}
var i = 100, j = 100;
outerloop:
while(i>0) {
  while(j>0) {
   j++

   if(j>50) {
     break outerloop;
   }
  }
i++

}
loop1:
for (let i = 0; i < 5; i++) {
  if (i === 1) {
    continue loop1;
  }
  str = str + i;
}

JavaScript\Logical And/Or

10th January 2021 at 8:15pm
JavaScriptCode Numbers

If a value can be converted to true, the value is so-called truthy. If a value can be converted to false, the value is so-called falsy.

Examples of expressions that can be converted to false are:

  • null
  • NaN
  • 0
  • empty string ( "" or '' ) or empty template literal ( `` )
  • undefined

The logical OR expression is evaluated left to right, and first truthy returned expression stops evaluation of the remaining expressions

The && operator is executed before the || operator

Note: If you use this operator to provide a default value to some variable, be aware that any falsy value will not be used. If you only need to filter out null or undefined, consider using the nullish coalescing operator ( ?? )

JavaScript\Multi-line string

8th January 2021 at 11:01am
Formatting JavaScriptCode Text

It's not a multiline string, it's a one line string split over multiple lines of code that make up a single statement.

Old version uses backslash as a line continuation character:

eval(" \
alert('hi'); \
");

New version uses backtick character as multi-line string:

WARNING: Not supported by IE

eval(`
alert('hi');
`);

Use string concatenation instead:

eval(
"var v1 = 'hi';" +
"alert(v1);"
);

JavaScript\Run in HTML Document

8th January 2021 at 11:01am
HTMLCode JavaScriptCode UserAction
<html>
  <body><script type = "text/javascript">window.onerror=function(msg,url,line){alert("Line number = "+line+"\nMessage:\n\n"+msg)}</script>
    <script type="text/javascript">
alert('hi';
      </script>
    </body>
  </html>

JavaScript\Strict Mode

10th January 2021 at 7:31pm
CodeLibrary JavaScriptCode Text

Show strict mode compilation errors on specific scripts or functions

  • First statement in script or function: 'use strict'; or "use strict";
  • Note: Strict mode applies to entire scripts or to individual functions, not individual block statements enclosed in {} braces within a function
  • Note: Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally
  • Note: The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it

MozillaDeveloper Strict mode

->

Sample data

"use strict";
mistypeVariable = 17;

Result in Developer Tools, Javascript Console:

Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLineNumber
<script type="module">
mistypeVariable = 17;
</script>

Result:

Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLine

JavaScript\String Escape Codes

8th January 2021 at 11:01am
CodeLibrary JavaScriptCode Text

Here are all the string escape codes:

\0 The NUL character (\u0000)
\b Backspace (\u0008)
\t Horizontal tab (\u0009)
\n Newline (\u000A)
\v Vertical tab (\u000B)
\f Form feed (\u000C)
\r Carriage return (\u000D)
\" Double quote (\u0022)
\' Apostrophe or single quote (\u0027)
\\ Backslash (\u005C)
\x XX The Latin-1 character specified by the two hexadecimal digits XX
\u XXXX The Unicode character specified by the four hexadecimal digits XXXX

JavaScript\This object

8th January 2021 at 11:00am
CodeLibrary JavaScriptCode

JavaScript This Parameter

->

Functions called via property references get "this" set for them: This is the part that really makes it seem like JavaScript has methods: The "this" reference gets set automagically to the object instance if you call a function via a property reference.

Within that call, use the object in question as "this". Getting the function reference from an object property doesn't link it in any way to the object the property came from. The JavaScript engine treats calls of functions just retrieved from object properties as special and sets up "this" accordingly. Essentially, "this" is just a function argument that's passed into the function as an implicit feature of calling a function via a property reference.

JavaScript gives us the call and apply methods on function instances, with which we can say explicitly what we want "this" to be. If you say myfunction.call(myobject), you're saying "call myfunction and use myobject as 'this'", which is what the property-retrieval stuff does implicitly for you.

UrObject.UrFunction();

- equates to -

UrObject.UrFunction.call(UrObject);

Everything can be seen as a function.

window['UrObject']['UrFunction'].call(window['UrObject']);

Getting the function reference from the property (UrObject.UrFunction) is distinct from the fact we're calling it (call) is distinct from what "this" should be ((UrObject)).

JavaScript Closures

->

The interpreter creates a call object for this particular execution of the function and sets some properties on that call object before passing it into the function's code.

  • A property called arguments which is an array (of sorts, in most implementations it's not actually an Array object) of the actual arguments we called the function with, plus a callee property which is a reference to the function being called.
  • A property for each of the arguments defined by the function declaration. The values of these properties are set to the values passed into the function. If any arguments weren't specified (because JavaScript lets you call functions with however many arguments you want, regardless of the definition), properties for any missing arguments are still created on the call object — with the value undefined.
  • A property for every declared variable within the function (e.g., every "var" statement). (These start out with the value undefined.)
window.UrFunction(UrObject1, UrObject2);

That creates a call object for this execution of updateDisplay that essentially looks like this:

call.arguments = [UrObject1, UrObject2]
call.arguments.callee = UrFunction
call.ur_input_parm1 = UrObject1
call.ur_input_parm2 = UrObject2
call.internal_var1 = undefined

The use of the call object is implicit, because once the call object is created, it's put at the top of the scope chain for the duration of the function call.

JavaScript\TypeOf Name

10th January 2021 at 8:41pm
CodeLibrary JavaScriptCode Text

Get string representing object type

  • typeof always returns a string
  • Note: typeof operator takes precedence over string concatenation ( + )
  • Note: type a let or const variable in a block before they are declared will throw a ReferenceError
  • Undefined, undeclared variable, or unassigned variable = "undefined"
  • Boolean(1), !!(1) = "boolean"
  • Number('321') , Infinity, NaN = "number"
  • Bigint, 321n = "bigint"
  • String = "string"
  • Symbol = "symbol"
  • Function() {}, class UrClassName {}, = "function"
  • null, object, {ur_prop_name: ur_prop_value}, [ur_val1, ur_val2, ur_val3], new Date(), /regex/ = "object"

JavaScriptBookmarklets

25th December 2020 at 10:51pm
DOC

JavaScriptBookmarklets\Bibliographic citation

27th February 2021 at 5:17am

ALAorg Citations bookmarklet

->

javascript:(function(){var h=document.createElement('div');var t=document.getElementsByTagName('title')[0];var info='<p><strong>Title('+t.innerHTML.length+'):</strong> '+t.innerHTML+'</p>';var m=document.getElementsByTagName('meta');for(var i=0;i < m.length;i++){if(null !==m[i].getAttribute('name')){var c=m[i].getAttribute('content');info+='<p><strong>'+m[i].getAttribute('name')+'('+c.length+'):</strong> '+c+'</p>';}}var lm=document.lastModified;var url=location.href;var d=new Date();var dd=d.getDate();var mm=d.getMonth()+1;var yyyy=d.getFullYear();info+='<p><strong>Citation: </strong>"' + t.innerHTML + '." Last modified '+lm+'. <a target="_blank" href="'+url+'">'+url+'</a> (accessed '+mm+'/'+dd+'/'+yyyy+').</p>';document.body.insertBefore(h,document.body.firstChild);h.innerHTML='<div style="border:1px solid %23888;border-radius:5px;-moz-box-shadow:0 0 5px %23888;-webkit-box-shadow:0 0 5px%23888;box-shadow:0 0 5px %23888;background:%23eee;text-align:left;padding:1em;"><a href="%23" onclick="document.body.removeChild(document.body.firstChild);return false">remove</a>'+info+'</div>';})();

JavaScriptBookmarklets\Clear all CSS

6th March 2021 at 6:33pm

Clears all the CSS Class and Style attributes

avascript:(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["module"], factory);
  } else if (typeof exports !== "undefined") {
    factory(module);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod);
    global.clearAllCSS = mod.exports;
  }
})(this, function (module) {
  "use strict";

  var each = Array.prototype.forEach;


  function clearAllCSS(nest_level, cur_elt) {
    var _context2;
    if (!cur_elt) {
        throw new Error("No element specified.");
        }

    var _context;
    (_context = cur_elt.children, each).call(_context, function (child) {
        clearAllCSS(nest_level+1, child);
        });

    while(cur_elt.attributes.length > 0) {
        cur_elt.removeAttribute(cur_elt.attributes[0].name);
        }
    }

  module.exports = clearAllCSS;
});
document.querySelectorAll('iframe,script,noscript').forEach(function(element){if (element!=null){element.parentNode.removeChild(element)}});
clearAllCSS(1, document.body);
if (document.head!=null){document.head.parentNode.removeChild(document.head)};
document.querySelectorAll('link').forEach(function(element){if (element!=null){element.parentNode.removeChild(element)}});
document.body.style.fontSize=prompt("Please enter font multiplier", "2") + "00%";
undefined;

JavaScriptBookmarklets\Convert to Inline CSS

1st March 2021 at 5:42pm

Run this script (it takes a while) and then save the web page. All the CSS properties are specified on each element, so it does not need to load any stylesheets.

GitHub LukeHorvat Computed Style to Inline

->

avascript:(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["module"], factory);
  } else if (typeof exports !== "undefined") {
    factory(module);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod);
    global.computedStyleToInlineStyle = mod.exports;
  }
})(this, function (module) {
  "use strict";

  var each = Array.prototype.forEach;


  function computedStyleToInlineStyle(nest_level, parent_style, cur_elt) {
    var _context2;
    if (!cur_elt) {
        throw new Error("No element specified.");
        }

    var cur_style = getComputedStyle(cur_elt);
    var _context;
    (_context = cur_elt.children, each).call(_context, function (child) {
        computedStyleToInlineStyle(nest_level+1, cur_style, child);
        });

    var parent_copy = document.createElement("an_unknown_tag");
    if (nest_level > 1) {
        for (var pctr = 0; pctr < parent_style.length; pctr++) {
            var pname = parent_style[pctr];
            var pval = parent_style.getPropertyValue(pname);
            parent_copy.style[pname] = pval;
            }
        }

    var blank_element = document.createElement("an_unknown_tag");
    parent_copy.appendChild(blank_element);
    document.head.appendChild(parent_copy);
    var blank_style = getComputedStyle(blank_element);

    for (var dctr = 0; dctr < blank_style.length; dctr++) {
        if (dctr < cur_style.length) {
            var dname = blank_style[dctr];
            var dval = blank_style.getPropertyValue(dname);
			var cval = cur_style.getPropertyValue(dname);
            if (cval != dval && cur_elt.style[dname] != dval) {
                cur_elt.style[dname] = cval;
                }
            }
        }
    }

  module.exports = computedStyleToInlineStyle;
});
(function(){
	var h = document.createElement('div');
	var t = document.getElementsByTagName('title')[0];
	var cite_remove = '<a href="%23" onclick="document.body.firstChild.style.visibility = \'hidden\';document.body.firstChild.style.height = \'0px\';return false">remove</a>';
	var info = '<p><strong>Title(' + t.innerHTML.length + '):</strong> ' + t.innerHTML + '</p>';
	var m = document.getElementsByTagName('meta');
	for(var i = 0; i < ((m == null) ? 0 : m.length); i++) {
		if(null !== m[i].getAttribute('name') ) {
			var c=m[i].getAttribute('content');
			if (c != null) {info += '<p><strong>' + m[i].getAttribute('name') + '(' + c.length + '):</strong> ' + c + '</p>';}
			}
		}
	
	var lm = document.lastModified;
	var url = location.href;
	var d = new Date();
	var dd = d.getDate();
	var mm = d.getMonth()+1;
	var yyyy = d.getFullYear();
	info += '<p><strong>Citation: </strong>"' + t.innerHTML + '." Last modified ' + lm + '. <a target="_blank" href="' + url + '">' + url + '</a> (accessed ' + mm + '/' + dd + '/' + yyyy + ').</p><p><strong>Filename:</strong> ' + '0'.repeat(4-yyyy.toString().length) + yyyy + 'm'+'0'.repeat(2-mm.toString().length) + mm + 'd' + '0'.repeat(2-dd.toString().length) + dd + ' ' + url.replace('http://','').replace('https://','').replace('file:///','').replaceAll('/','-fslash-') + '.html</p>';
	document.body.insertBefore(h,document.body.firstChild);
	h.innerHTML='<div style="border:1px solid %23888;border-radius:5px;-moz-box-shadow:0 0 5px %23888;-webkit-box-shadow:0 0 5px%23888;box-shadow:0 0 5px %23888;background:%23eee;text-align:left;padding:1em;">' + cite_remove + info + cite_remove + '</div>';
	})();
document.querySelectorAll('iframe,script,noscript').forEach(function(element){element.parentNode.removeChild(element)});
computedStyleToInlineStyle(1, null, document.body);
document.head.parentNode.removeChild(document.head);
document.querySelectorAll('link').forEach(function(element){element.parentNode.removeChild(element)});
alert("done");

JavaScriptBookmarklets\Edit current page

27th February 2021 at 4:32am

Edit webpage

javascript:document.body.contentEditable = 'true'; document.designMode='on'; void 0

Editing Done

javascript:document.body.contentEditable = 'false'; document.designMode='off'; void 0

JavaScriptBookmarklets\Extract iFrame pages

8th January 2021 at 11:00am
Extract FileSystem HTMLCode JavaScriptCode
(function(){ var imgs = document.getElementsByTagName('iframe'),t=[]; for (var i=0, n=imgs.length;i'+ imgs[i].src+''); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract images

8th January 2021 at 11:00am
Extract FileSystem HTMLCode JavaScriptCode
avascript:(function(){ var imgs = document.getElementsByTagName('img'),t=[]; for (var i=0, n=imgs.length;i<n;i++) t.push('<a href="'+imgs[i].src+'"><img src="'+ imgs[i].src+'" width="100"></a>'); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract plain text

8th January 2021 at 11:00am
Extract JavaScriptCode Text

Copy the HTML body to a new window, so CSS and Javascript are ignored

avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML;void(newWindow.focus());}

Copy the HTML body to a new window showing the HTML tags, so you can see the HTML code

avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/&/g,"&amp;").replace(/</g,"<br>&lt;");void(newWindow.focus());}

Copy the HTML body without any HTML tags, so the text is loaded without any HTML or CSS styling

avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/<[^>]+>/g, '<br>');void(newWindow.focus());}

JavaScriptBookmarklets\Unescape HTML code

3rd March 2021 at 2:38am
avascript:document.documentElement.innerHTML='<html><body>'+document.body.innerHTML.replaceAll('&lt;','<').replaceAll('&gt;','>').replaceAll('&amp;','&')+'<\/body><\/html>';

JavaScriptBookmarklets\View HTML Source

1st March 2021 at 5:28pm
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){;newWindow.document.documentElement.innerHTML='<html><head><title>Source of Page<\/title><\/head><body><pre>'+document.documentElement.outerHTML.replaceAll('&','&amp;').replaceAll('<','&lt;')+'<\/pre><\/body><\/html>';newWindow.document.body.contentEditable = 'true'; newWindow.document.designMode='on';void(newWindow.focus());}

JavaScriptBookmarklets\View HTML to TW

5th March 2021 at 8:27pm
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){;newWindow.document.documentElement.innerHTML='<html><head><title>Source of Page<\/title><\/head><body><pre>'+document.documentElement.outerHTML.replaceAll('&','&amp;').replaceAll('<','&lt;').replaceAll('&lt;html','&lt;div').replaceAll('&lt;\/html','&lt;\/div').replaceAll('&lt;body','&lt;div').replaceAll('&lt;\/body','&lt;\/div').replaceAll('position: absolute','position: relative').replaceAll('position: fixed','position: relative').replaceAll('position: flex','position: relative').replaceAll('>remove&lt;\/a>','&gt;&lt\/a&gt;').replaceAll('src="http','src_attr="http').replaceAll('src=\'http','src_attr=\'http')+'<\/pre><\/body><\/html>';newWindow.document.body.contentEditable = 'true'; newWindow.document.designMode='on';void(newWindow.focus());}

keyboard action FontLarge

6th March 2021 at 8:03pm
$:/positivesigner/text-ref $:/tags/KeyboardShortcut

keyboard action FontNormal

6th March 2021 at 8:03pm
$:/positivesigner/text-ref $:/tags/KeyboardShortcut

keyboard action HomeTiddlers

6th March 2021 at 7:32pm
$:/positivesigner/home-button $:/tags/KeyboardShortcut

keyboard action SaveAllChanges

6th March 2021 at 7:58pm
$:/positivesigner/base-install $:/tags/KeyboardShortcut

mcr glbl_article_list

9th March 2021 at 10:27pm
$:/positivesigner/text-ref $:/tags/Macro

mcr glbl_code_split

6th March 2021 at 8:07pm
$:/positivesigner/text-ref $:/tags/Macro

mcr glbl_compare_lines

6th March 2021 at 8:07pm
$:/positivesigner/text-ref $:/tags/Macro

mcr glbl_dt_ddd

6th March 2021 at 8:04pm
$:/positivesigner/text-ref $:/tags/Macro

mcr glbl_ext

6th March 2021 at 8:29pm
$:/positivesigner/text-ref $:/tags/Macro

MicrosoftRemoteDesktop

8th January 2021 at 1:31am
DOC

MicrosoftRemoteDesktop\Setup PC

8th January 2021 at 10:59am
AndroidOS UserAction WindowsOS

Panel

6th March 2021 at 7:58pm
$:/positivesigner/text-ref
  • If there is an existing personal access token,
  • Click on the name -> Navigates page
  • Click button Regenerate Token -> Navigates page
  • Click button Copy to Clipboard
  • Otherwise create a new token
  • Note = name of end user and device
  • Must be unique
  • Each device should get a different token
  • checkbox "repo" = set
  • Click button Generate token -> Navigates page
  • Click button Copy to Clipboard

  • [Saving tab, GitHub Saver sub-tab]
  • Paste into field "Password, OAUTH token, or personal access token"
  • Close the Control Panel card

  • Click button
  • Wait a few seconds for the "Saved wiki" notification
  • The token is saved in internal browser storage
  • If you get a "401" error, go back to step 1 to generate a new token

Recent Entries

6th March 2021 at 8:05pm
$:/positivesigner/text-ref

Regular Expressions

25th December 2020 at 10:51pm
DOC

Regular Expressions\Explanation

8th January 2021 at 10:57am
CodeLibrary RegExCode

TiddlyWiki\Regular Expression

Regexp Filter with brackets

->

The code would get complexer [sic] too as "[[...]]" can't be put directly in the regex in TW. You'd have to do it through a variable. And since "[character class]" is reserved in regex you'd also have to escape square brackets "[\[\]]".

Regular Expression Quantifiers

->

Regular expressions take a string of text, and returns a YES or NO as to whether it matches a character pattern.

You can specify a literal character.

  • A letter or series of letters
    • ABC matches B? -,/ABC\,- ABC split out B? -,/A\,- -,/C\,-
  • \. is a literal period, because without the \ escape it would have special meaning
    • AA.AA matches \.? -,/AA.AA\,- AA.AA split out \.? -,/AA\,- -,/AA\,-

You can use tokens to specify a kind of character to match.

  • \d is a numeric digit 0 through 9
    • A2C matches \d? -,/A2C\,- A2C split out \d? -,/A\,- -,/C\,-
  • \D is any non-numeric digit
    • 5A8 matches \D? -,/5A8\,- 5A8 split out \D? -,/5\,- -,/8\,-
  • \s is a whitespace character; like space, tab, or line feed
    • A C matches \s? -,/A C\,- A C split out \s? -,/A\,- -,/C\,-
  • \S is a non-whitespace character
    • A matches \S? -,/A\,- A split out \S? -,/\,- -,/\,-
  • \W is a whitespace or punctuation character (non-word character)
    • ; matches \W? -,/;\,- ; split out \W? -,/\,- -,/\,-
  • \w is a word character (non-whitespace and non-punctuation character)
    • A matches \w? -,/A\,- A split out \w? -,/\,- -,/\,-
  • . period is any character
    • A matches .? -,/A\,- A split out .? -,/\,- -,/\,-

You can get out of having to use the \ escape over a block of text if you prefer to type it out.

  • \QOne. Two. Three.\E treats anything between the delimiters as a literal string, like "One. Two. Three."
    • Useful to escape metacharacters
    • Otherwise the periods would be special characters applied to the one letter before each period
    • You can also write it as One\. Two\. Three\.

A regex quantifier such as + tells the regex engine to match a certain quantity of the character, token or subexpression immediately to its left.

  • A+ the quantifier + applies to A
    • AAABCCC matches B+? -,/AAABCCC\,- AAABCCC split out B+? -,/AAA\,- -,/CCC\,-
    • AAABBBCCC matches B+? -,/AAABBBCCC\,- AAABBBCCC split out B+? -,/AAA\,- -,/CCC\,-
  • A* the quantifier * applies to A
    • ABBBC matches B*? -,/ABBBC\,- ABBBC split out B*? -,/A\,- -,/C\,-
    • AC matches B*? -,/AC\,- AC split out B*? -,/A\,- -,/C\,-
  • ABC? the quantifier ? applies to the C—not to ABC
    • ABCD matches BC?? -,/ABCD\,- ABCD split out BC?? -,/A\,- -,/D\,-
    • ABD matches BC?? -,/ABD\,- ABD split out BC?? -,/A\,- -,/D\,-
  • (?:A|B|C)+ the quantifier + applies to the subexpression
    • ABCD matches (?:B|C)+? -,/ABCD\,- ABCD split out (?:B|C)+? -,/A\,- -,/D\,-
    • ABD matches (?:B|C)+? -,/ABD\,- ABD split out (?:B|C)+? -,/A\,- -,/D\,-
  • \QA.B.C\E+ is treated as a sequence of literals, so the quantifier only applies to the last character
    • This could also be written as A\.B\.C+

By default, a quantifier tells the engine to match as many instances of its quantified token or subpattern as possible. This behavior is called greedy.

  • A+ is greedy, and matches all the number characters in a row from the starting point where exists (a number)
    • ABBBCD matches B+? -,/ABBBCD\,- ABBBCD split out B+? -,/A\,- -,/CD\,-
  • A+B is greedy, and matches all the number characters in a row where exists (a letter B after a letter A)
    • ABBBCD matches B+C? -,/ABBBCD\,- ABBBCD split out B+C? -,/A\,- -,/D\,-
    • ABBBCD matches (B+)C? -,/ABBBCD\,- ABBBCD split out (B+)C? -,/A\,- -,/BBB\,- -,/D\,-

In contrast to the standard greedy quantifier, which eats up as many instances of the quantified token as possible, a lazy (sometimes called reluctant) quantifier tells the engine to match as few of the quantified tokens as needed.

  • \w*?B is lazy, and matches as few word characters in a row as needed where exists (a letter B after a word character)
    • +ABCCC+ matches \w*?C? -,/+ABCCC+\,- +ABCCC+ split out \w*?C? -,/+\,- -,/\,- -,/\,- -,/+\,-
    • +ABCCC+ matches \w*C? -,/+ABCCC+\,- +ABCCC+ split out \w*C? -,/+\,- -,/+\,-

In contrast to the standard docile quantifier, which gives up characters if needed in order to allow the rest of the pattern to match, a possessive quantifier tells the engine that even if what follows in the pattern fails to match, it will hang on to its characters.

  • A++ is possessive—it matches as many characters as needed and never gives any of them back.
    • Whereas the regex A+. matches the string AAA, A++. doesn't. At first, the token A++ greedily matches all the A characters in the string. The engine then advances to the next token in the pattern. The dot . fails to match because there are no characters left to match. The engine looks if there is something to backtrack. But A++ is possessive, so it will not give up any characters. There is nothing to backtrack, and the pattern fails. In contrast, with A+., the A+ would have given up the final A, allowing the dot to match.

You can specify a number range of characters to repeat.

  • A{2,9} uses two to nine As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
    • +ABCCC+ matches C{1,2}? -,/+ABCCC+\,- +ABCCC+ split out C{1,2}? -,/+AB\,- -,/\,- -,/+\,-
    • +ABCCC+ matches C{2,2}? -,/+ABCCC+\,- +ABCCC+ split out C{2,2}? -,/+AB\,- -,/C+\,-
    • +ABCCC+ matches C{2,9}? -,/+ABCCC+\,- +ABCCC+ split out C{2,9}? -,/+AB\,- -,/+\,-
  • A{2,} uses two or more As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
    • +ABCCC+ matches C{2,}? -,/+ABCCC+\,- +ABCCC+ split out C{2,}? -,/+AB\,- -,/+\,-

You can use negated character classs to match characters other up to the one you want.

  • ^[^\.]* skips up to first period
    • AB.C.D matches ^[^\.]*? -,/AB.C.D\,- AB.C.D split out ^[^\.]*? -,/\,- -,/.C.D\,-
  • ^.*\. skips up to last period
    • AB.C.D matches ^.*\.? -,/AB.C.D\,- AB.C.D split out ^.*\.? -,/\,- -,/D\,-

Tempered Greedy Token Solution

  • A(?:(?!B).)*B stops at the first B instead of the last B
    • AB.C.DCE matches B(?:(?!C).)*C? -,/AB.C.DCE\,- AB.C.DCE split out B(?:(?!C).)*C? -,/A\,- -,/.DCE\,-
    • AB.C.DCE matches B.*C? -,/AB.C.DCE\,- AB.C.DCE split out B.*C? -,/A\,- -,/E\,-
  • A(?:(?!C)(?!B).)*B stops at the first B unless there is a C between the A and B
    • AB.CA matches B(?:(?!D)(?!C).)*C? -,/AB.CA\,- AB.CA split out B(?:(?!D)(?!C).)*C? -,/A\,- -,/A\,-
    • AB.CAB.FGHBC matches B(?:(?!D)(?!C).)*C? -,/AB.CAB.FGHBC\,- AB.CAB.FGHBC split out B(?:(?!D)(?!C).)*C? -,/A\,- -,/A\,- -,/\,-
    • AB.CAB.DFGHBC matches B(?:(?!D)(?!C).)*C? -,/AB.CAB.DFGHBC\,- AB.CAB.DFGHBC split out B(?:(?!D)(?!C).)*C? -,/A\,- -,/AB.DFGH\,- -,/\,-

Search All Fields

6th March 2021 at 8:05pm
$:/positivesigner/text-ref



SQLite

25th December 2020 at 10:51pm
DOC

SQLite\Blob text

8th January 2021 at 10:56am
AssignVariable Filter SQLCode

SQLite Blob text

->

WITH RECURSIVE test(c,cur) as (
     SELECT '', HEX(blob_field) FROM UrTable WHERE UrPK = 6
   UNION ALL
    select c || char((case substr(cur,1,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,1,1) end)*16
               + (case substr(cur,2,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,2,1) end)),
substr(cur,3)
from test where length(cur)>0
)
select * from test

SQLite\Database Browser

8th January 2021 at 10:55am
Extract FileSystem SQLCode WindowsOS

SQLite DB Browser

->

I used DB Browser for SQLite - .zip (no installer) for 64-bit Windows

SQLite\Information Schema

8th January 2021 at 10:55am
Extract FileSystem SQLCode

SQLite schema information

->

SELECT name, sql FROM sqlite_master
WHERE type='table'
ORDER BY name;

SQLite Language functions

->

sqlite_source_id()

--version string of SQLite Library source code
2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f

sqlite_version()

--version string of SQLite Library running
3.33.0

SQLite\String Manipulation

8th January 2021 at 10:45am
Extract SQLCode Text

SQLite Language functions

->

--comment

CHAR(unicode_char_list)

COALESCE(field_list)

HEX(field)

IFNULL(field, default_text)

INSTR(field, search_text)

LENGTH(field)

LIKE(field, comparison_text)

  • field LIKE comparisontext
  • LIKE(field, comparison_text, escape_char)

LOWER(field)

LTRIM(field)

  • LTRIM(field, chars_to_remove)

PRINTF(format_text, field_list)

REPLACE(field, search_text, new_text)

RTRIM(field)

  • RTRIM(field, chars_to_remove)

SUBSTR(field, start_char)

  • SUBSTR(field, start_char, char_count)

TRIM(field)

  • TRIM(field, chars_to_remove)

typeof(field)

  • "null", "integer", "real", "text", or "blob".

UNICODE(number)

UPPER(field)

SQLite\Top or Limit records

8th January 2021 at 10:45am
Filter Numbers SQLCode

SQLite Top 5 Records

->

SELECT * FROM Table_Name LIMIT 5;

Tags Count Audit

6th March 2021 at 8:05pm
$:/positivesigner/text-ref

template ExportAllCode

6th March 2021 at 8:06pm
$:/positivesigner/base-install $:/tags/Exporter


$:/config/MissingLinks

no

$:/config/Navigation/openLinkFromOutsideRiver

bottom

$:/config/Navigation/Permalinkview/CopyToClipboard

no

$:/config/ShortcutInfo/font-large


$:/config/ShortcutInfo/font-normal


$:/config/ShortcutInfo/home-tiddlers


$:/config/ShortcutInfo/save-all-changes


$:/config/shortcuts/font-large

ctrl-shift-Quote

$:/config/shortcuts/font-normal

ctrl-shift-Comma

$:/config/shortcuts/home-tiddlers

alt-H

$:/config/shortcuts/save-all-changes

alt-S

$:/config/TextEditor/EnableToolbar

no

$:/config/ViewToolbarButtons/Visibility/$:/positivesigner/gcmpr/btn gcmpr card

hide

$:/config/WikiParserRules/Inline/wikilink

disable

$:/DefaultTiddlers

[tag[INDEX]has[sort_ord]sort[title]]
[tag[INDEX]!has[sort_ord]sort[title]]

$:/language/DefaultNewTiddlerTitle

New Card

$:/positivesigner/base-install

\define show_pill()
<<tag-pill tag:"$(cur_entry)$" >>
\end
---
<$list variable=cur_entry filter="[prefix[$:/positivesigner/]is[tag]sort[]]">

<<cur_entry>>
</$list>

$:/positivesigner/div-pop


$:/positivesigner/gcmpr


$:/positivesigner/gcmpr/btn gcmpr card

<<gcmpr_btn_cmp_current>> 

$:/positivesigner/gcmpr/mcr gcmpr_compare_card

\define gcmpr_compare_card(ur_ttb_card)
<$list variable=ttb_card filter="[[$ur_ttb_card$]!match[]]">
<$list variable=compare_card filter="[<ttb_card>addprefix[$:/state/popup/compare-card/]]">
<$link to=<<ttb_card>> />
<<gcmpr_ref_edit_source_text>>
<<gcmpr_ref_copy_over_ttb_card>>
<br>
<$link to=<<compare_card>> />
<<gcmpr_ref_replace_comment_endings>>
<<gcmpr_ref_disp_diff_text>>
<$edit-text autoHeight=no tiddler=<<compare_card>> tag=textarea default="" />
<<gcmpr_ref_disp_textedit_link>>
</$list><!--compare_card-->
</$list><!--ttb_card-->
<!--gcmpr_compare_card-->
\end

\define gcmpr_ref_edit_source_text(ttb_card, compare_card)
<$vars enr_text="text" >
<$list variable=source_text filter="[<ttb_card>get<enr_text>else[]]">
<$button>
<$action-setfield $tiddler=<<compare_card>> text=<<source_text>> />
Copy Source
</$button>
</$list><!--source_text-->
</$vars><!--enr_text-->
<!--gcmpr_ref_edit_source_text-->
\end

\define gcmpr_ref_copy_over_ttb_card(ttb_card, compare_card)
<$vars enr_text="text" >
<$list variable=compare_text filter="[<compare_card>get<enr_text>else[]]">
<$button>
<$action-setfield $tiddler=<<ttb_card>> text=<<compare_text>> />
Overwrite Source
</$button>
</$list><!--compare_text-->
</$vars><!--enr_text-->
<!--gcmpr_ref_copy_over_ttb_card-->
\end

\define gcmpr_ref_replace_comment_endings(ttb_card, compare_card)
<$button>
<$vars comment_flag="--" lit_exclm="!" lit_lt="<" lit_gt=">" enr_text="text" >
<$wikify name=lit_lf text="&#10;">
<$list variable=comment_open_text filter="[<lit_lt>addsuffix<lit_exclm>addsuffix<comment_flag>]">
<$list variable=comment_close_text filter="[<comment_flag>addsuffix<lit_gt>]">
<$list variable=comment_close_replace filter="[<comment_flag>addsuffix<lit_exclm>addsuffix<lit_gt>]">
<$list variable=replace_text filter="[<compare_card>get<enr_text>split<comment_close_text>join<comment_close_replace>addprefix<lit_lf>addprefix<comment_open_text>addsuffix<lit_lf>addsuffix<comment_close_text>]">
<$action-setfield $tiddler=<<compare_card>> text=<<replace_text>> />
</$list><!--replace_text-->
</$list><!--comment_close_replace-->
</$list><!--comment_close_text-->
</$list><!--comment_open_text-->
</$wikify>
</$vars><!--comment_flag, lit_exclm, lit_lt, lit_gt-->
Replace comment endings
</$button><br>
<!--gcmpr_ref_replace_comment_endings-->
\end

\define gcmpr_ref_disp_diff_text()
<$list variable=val_ttb_card filter="[<ttb_card>get[text]!match[]]">
<$list variable=val_compare_card filter="[<compare_card>get[text]!match[]]">
<$diff-text source=<<val_ttb_card>> dest=<<val_compare_card>> />
</$list><!--val_compare_card-->
</$list><!--val_ttb_card-->
<!--gcmpr_ref_disp_diff_text-->
\end

\define gcmpr_ref_disp_textedit_link()
<$list variable=cur_url filter="[{$:/info/url/full}]">
<$list variable=new_link filter="[<cur_url>addsuffix[#]addsuffix[$:/positivesigner/gcmpr/textarea]split[$:]join[%24%3A]]">
<a href=<<new_link>> target="_blank" >text editor</a>
</$list>
</$list>
<!--gcmpr_ref_disp_textedit_link-->
\end

\define gcmpr_btn_cmp_current()
<$list variable=cur_card filter="[all[current]]">
<$list variable=dest_card filter="[<cur_card>addprefix[$:/state/popup/gcmpr/]]">
<$vars lit_lt="<" lit_gt=">" lit_s=" " lit_qs='"' macro_name="gcmpr_compare_card" enr_text="text" >
<$list variable=macro_call_text filter="[<lit_lt>addsuffix<lit_lt>addsuffix<macro_name>addsuffix<lit_s>addsuffix<lit_qs>addsuffix<cur_card>addsuffix<lit_qs>addsuffix<lit_gt>addsuffix<lit_gt>]">
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler=<<dest_card>> text=<<macro_call_text>> />
<$action-navigate $to=<<dest_card>> />
Compare to Textbox
</$button>
</$list><!--macro_call_text-->
</$vars><!--lit_lt-->
</$list><!--dest_card-->
</$list><!--cur_card-->
<!--gcmpr_btn_cmp_current-->
\end

\define gcmpr_textarea_new()
<$vars enr_text="text" enr_new_filename="new_filename" enr_rows="rows" enr_cols="cols" enr_disp_btn_incr_decr="disp_btn_incr_decr" lit_state_popup_prefix="$:/state/popup/gcmpr_textarea/" lit_default_rows="20" lit_default_cols="160" cur_card=<<currentTiddler>> >
<$list variable=temp_card filter="[<cur_card>addprefix<lit_state_popup_prefix>]">
New file name:
@@margin-left:5px;
<$edit-text tiddler=<<temp_card>> field=new_filename placeholder="" autoHeight=yes tag=input/>
@@
<$list variable=val_disp_btn_incr_decr filter="[<temp_card>get<enr_disp_btn_incr_decr>!match[]else[]]">
<$list variable=val_rows filter="[<temp_card>get<enr_rows>!match[]!match[0]else<lit_default_rows>]">
<$list variable=val_cols filter="[<temp_card>get<enr_cols>!match[]!match[0]else<lit_default_cols>]">
<$list variable=val_new_filename filter="[<temp_card>get<enr_new_filename>!match[]]">
<$list variable=new_card filter="[<val_new_filename>addprefix<lit_state_popup_prefix>]">
<$list variable=new_temp_card filter="[<new_card>addprefix<lit_state_popup_prefix>]">
<$list variable=filter_newcard_not_exists filter="[<new_card>!is[tiddler]]">
<$button>
<$list variable=cur_card_text filter="[<cur_card>get<enr_text>]">
<$action-setfield $tiddler=<<new_card>> $field=<<enr_text>> $value=<<cur_card_text>> />
</$list><!--cur_card_text-->
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_new_filename>> $value=<<val_new_filename>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_rows>> $value=<<val_rows>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_cols>> $value=<<val_cols>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_disp_btn_incr_decr>> $value=<<val_disp_btn_incr_decr>> />
<$action-navigate $to=<<new_card>> />
New card
</$button>
</$list><!--filter_newcard_not_exists-->
</$list><!--new_temp_card-->
</$list><!--new_card-->
</$list><!--val_new_filename-->

<br>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>!match[]]">
@@margin-right:20px;
<$button>
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_disp_btn_incr_decr>> $value="" />
Show Resize buttons
</$button>
@@
</$list><!--filter_disp_buttons-->
Rows: <<val_rows>>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>match[]]">
<$button>
<$list variable=val_new_rows filter="[<val_rows>add[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_rows>> $value=<<val_new_rows>> 
/>
</$list><!--val_new_rows-->
+
</$button>
<$list variable=filter_zero_rows filter="[<val_rows>!match[0]]">
<$button>
<$list variable=val_new_rows filter="[<val_rows>subtract[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_rows>> $value=<<val_new_rows>> />
</$list><!--val_new_rows-->
-
</$button>
</$list><!--filter_zero_rows-->
</$list><!--filter_disp_buttons-->
Cols: <<val_cols>>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>match[]]">
<$button>
<$list variable=val_new_cols filter="[<val_cols>add[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_cols>> $value=<<val_new_cols>> />
</$list><!--val_new_cols-->
+
</$button>
<$list variable=filter_zero_cols filter="[<val_cols>!match[0]]">
<$button>
<$list variable=val_new_cols filter="[<val_cols>subtract[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_cols>> $value=<<val_new_cols>> />
</$list><!--val_new_cols-->
-
</$button>
@@margin-left:20px;
<$button>
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_disp_btn_incr_decr>> $value="hide" />
Hide resize buttons
</$button>
@@
</$list><!--filter_disp_buttons-->
</$list><!--filter_zero_cols-->
<br>
<textarea rows=<<val_rows>> cols=<<val_cols>> />
</$list><!--val_cols-->
</$list><!--val_rows-->
</$list><!--val_disp_btn_incr_decr-->
</$list><!--temp_card-->
</$vars><!--enr_new_filename-->
\end

\define glbl_chk(ur_field)
<br><$checkbox tiddler=<<currentTiddler>> field="$ur_field$" unchecked="no" checked="yes"></$checkbox><span style="margin-right:5px;" />
\end

$:/positivesigner/gcmpr/textarea

<<gcmpr_textarea_new>>

$:/positivesigner/home-button


$:/positivesigner/text-ref


$:/themes/tiddlywiki/vanilla/options/sidebarlayout

fluid-fixed

AndroidChromeBrowser

<<glbl_article_list>>

AndroidChromeBrowser\Desktop Shortcut to Website

"""
This does not work for file:///sdcard HTML files
Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Google Chrome app]
- [Non-incognito mode]
- Navigate to website page
- Note: This does not work for file:///sdcard HTML files
- [Top-right icons]
- Click the three-lines menu, option Add to Home screen -> Opens dialog
- [Add to Home screen dialog]
- Shortcut name / UrShortcutName
- Click button Add -> Closes dialog

[Desktop icons]
- Click icon UrShortcutName -> Opens browser

AndroidGit

<<glbl_article_list>>

AndroidGit\Pocket Git pull repository updates

"""
[Pocket Git app]
- [Repositories List page, Top-right icons]
- Click button Preferences (looks like three lines) -Navigates page
- [Preferences page, Defaults section]
- Click link Default Directory -> Opens dialog
- [Select Folder dialog]
- Select the Downloads folder -> Closes dialog
- [Preferences page, Defaults section]
- Note: Default Directory = /storage/emulated/0/Download
- Click button Back (looks like a left arrow) -> Navigates page

- [Repositories List page, Bottom-right icons]
- Click button Create Project (looks like a red button with a Plus sign) -> Opens dialog
- [Create Project dialog]
- Project Name = UrProjectName
- Clone URL = UrRepositoryURL
- Note: Local Path automatically creates a sub-directory under the Downloads folder
- Click the Authentication drop-list, option Password
- Username = UrRepositoryUsername
- Password = UrRepositoryPassword
- [Create Project dialog, Top-right icons]
- Click button Save (looks like a floppy disk) -> Closes dialog

- [Repositories List page]
- Click repository UrProjectName -> Navigates page

- [Repository page, Top-right icons]
- Click the Remotes menu (looks like a cloud), click option Fetch -> Starts process
- Wait for popup message "Finished fetching"
- Click the Remotes menu, click option Pull -> Starts process
- Wait for popup message "Finished pulling"

[File system]
- [Downloads folder]
- Note: All the files in the repository are available under the UrProjectName sub-folder in the Downloads folder

AndroidMultipleUsers

<<glbl_article_list>>

AndroidMultipleUsers\Common access files

"""
When you change users on an Android device, the file:///sdcard/ folder is aliased to a different location for each. There is a specific sub-folder that is aliased to the same location for all users.

[File Manager]
- Navigate to /sdcard/Android/obb
- Create a folder and copy files into it

[Android Notices menu]
- Change the current user

[File Manager]
- Navigate to /sdcard/Android/obb
- You can see the same folder and files from the other login

AndroidProgramming

<<glbl_article_list>>

AndroidProgramming\DCoder

Note: I found that the DCoder app actually submitted the VB code to a web server. So there was no way for me to access the local file system.

```
  'Visual Basic.Net Compiler version 0.0.0.5943 (Mono 4.0.1)

Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Namespace Dcoder
  Public Module Program
    Public Sub Main(args() As string)
      Dim strRET = "Hi"
      For Each strENTRY As String In SubDir_List("/")
          For Each strE2 As String In SubDir_List("/" & strENTRY)
          For Each strE3 As String In SubDir_List("/" & strENTRY)
              strRET &= vbLf & strENTRY & "/" & strE2 & "/" & strE3
          Next strE3
          Next strE2
      Next strENTRY
      
      strRET &= vbLf & "Done"
      Console.WriteLine(strRET)
    End Sub 'Main

    Public Function t1(ur_root_dir As String) As String
        Return "no"
    End Function

    Public Function SubDir_List(ur_root_dir As String) As System.Collections.Generic.List(Of String)
      Dim lstRET = New System.Collections.Generic.List(Of String)
      SubDir_List = lstRET
      Try
      Dim proc = New System.Diagnostics.Process
      Dim stg = new System.Diagnostics.ProcessStartInfo
      proc.StartInfo = stg
      stg.FileName = "ls"
      stg.Arguments = ur_root_dir

      'stg.FileName = "find"
      'stg.Arguments = ". -name '*' -print"

      stg.UseShellExecute = false
      stg.RedirectStandardOutput= true
      stg.RedirectStandardError = true
      stg.CreateNoWindow = true
      proc.Start()
      Dim strCL_OUT = proc.StandardOutput.ReadToEnd()
      'strRET = "[Output: " & vbLf & strCL_OUT & "]"
      'strRET &= vbLf & "(err: " & vbLf & proc.StandardError.ReadToEnd() & ")"
      For Each strENTRY As String In strCL_OUT.Split(CHR(10))
          If strENTRY <> "" Then
              lstRET.Add(strENTRY)
          End If
      Next strENTRY
      Catch ex As System.Exception
      End Try
    End Function 'SubDir_List
  End Module
End Namespace

AndroidQLua

<<glbl_article_list>>

AndroidQLua\Console Commands

"""
[QLua app]
- Click button Console -> Navigates page

- [console window]
- Note: The right-arrow symbol (greater-than sign) is the Lua prompt
- Note: Comment line-endings in a Lua file are separated by two hyhpens
"""

```
--Single-line comment
ur_object.ur_function() --Comment until end of line
```

"""
- Note: Multi-line comments in a Lua file are separated by two hyphens and two open brackets, and closed by two hyphens and two close brackets
"""

```
--[[
Block comment
multiple lines
--]]
```

"""
- Note: Commands in Lua are case sensitive
- - You can create functions named `abc`, `Abc`, `abC`, and `ABC`, and each one can store to a different value

- Note: Exiting the Lua interpreter returns to the Linux Shell command line interpreter that was created by QLua
- Run the `os.exit()` command
"""

```
os.exit()
```

"""
[Linux Shell CLI]
- Note: The $ symbol (dollar sign) is the Linux Shell prompt
- Note: Commands in Linux Shell are case sensitive
- - You can create programs named `abc`, `Abc`, `abC`, and `ABC`, and each one can run different code
- - Most standard Linux Shell commands are named with all lowercase characters, so only `abc` would be the standard way to name a program

- Note: Exiting the Linux Shell returns to the QLua app main page
- Run the `exit` command
"""

```
exit
```


AndroidQLua\Console Run a Program

"""
[Lua console]
- Note: I had problems using the `LoadString` function with the `loadfile` command
- - In the Lua code, replace any references to the `LoadString` function with the `Load` function
- - The `Load` command did not need extra escaping like`\\r` for the parameter, so replace `\\r` with `\r` when using the `Load` command
- Save the result of the loadfile command to create a new function from the file
"""

```
urfile_fn=loadfile('/sdcard/qlua5/ur_file.lua')
```

"""
- Note: This added a row to the _G table
- Note: Just typing a function name or a table name shows the type of data stored in the row
"""

```
_G.urfile
```

"""
- Output is `function: 0x#####`
- Note: any command except _G is an implied name lookup in the _G table
"""

```
urfile
```

"""
- Output is also the same `function: 0x####`
- Note: You can run a function by adding parentheses to the end of the function name
- Running a function can load additional functions into the _G table
"""

```
urfile()
```

"""
- Output is the Lua program output
- Note: Any functions or tables added to the _G table are available
- Note: You can load a Lua function and run it on the same line instead of storing the program in a variable by adding an extra pair of parentheses
"""

```
loadfile('/sdcard/qlua5/ur_file.lua')()
```

"""
- Output is the Lua program output

AndroidQLua\Deploy a Program Module

"""
Note: The `share/5.3` directory under the QLua5 folder is where Lua looks to load "program modules" that must be loaded to the _G array as a prerequisites to running the current program

[QLua Editor]
- Note: I had problems using the `LoadString` function with the `require` command
- - In the Lua code, replace any references to the `Load` function with the `LoadString` function
- - The `LoadString` command needs extra escaping like`\\r` for the parameter, so replace `\r` with `\\r` when using the `LoadString` command

- [Bottom bar]
- Click button Save-As (Looks like a page with a Plus in the bottom-right corner) -> Open dialog

- [Save As dialog]
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = `share`
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder `share`
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = `5.3`
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder `5.3`
- [Bottom bar]
- File name = UrFileName.lua
- Click button OK (looks like a checkmark)

[File Manager]
- Note: Your Lua program is stored in folder `/sdcard/qlua/share/5.3`

[Lua console]
- Note: The require command to loads and runs a program module
- - Do not include the path or the `.lua` file extension
"""

```
require 'UrFileName'
```

"""
- Output is the Lua program output

AndroidQLua\Editor Run a Program

"""
[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icon]
- Click button Open file (looks like a Tabbed folder) -> Opens dialog
- Select file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Note: You can change the source code and save again before each run

- [Bottom bar icons]
- Click button Run (looks like a right-arrow play button) -> Navigates page

- [console window]
- Note: The top line shows the current path and the Linux shell command used to show the editor
- Note: The output of your program is below the first line
- Note: The the last line says "Press enter to exit"

AndroidQLua\MxClasses Design

"""
I created some default functions that I need to see the key/value pairs in Lua tables

[def.lua]
- [def_tcompile]
- This creates a 'tcompile' function that concatenates a table's string values then loads the result as a new function
- [def_ti]
- This creates a 'ti' function that adds a new numbered row to a table
- [def_tia]
- This clears out a global table variable and creates a 'tia' function that calls the 'ti' function for that table without having to pass it in as a parameter
- [def_printk]
- This creates a 'printk' function that prints all the keys in a table, sorted alphabetically
- [def_printv]
- This creates a 'printv' function that prints all the values in a table, sorted alphabetically
- [def_tcopy]
- This creates a 'tcopy' function that copies all records from one table into another
- [def_printiv]
- This creates a 'printiv' function that prints all the values in a table, in their original order (good for numeric-keyed tables)
- [def_printkv]
- This creates a 'printkv' function that prints all keys and values in a table, sorted by key alphabetically
- [def_ioexec]
- This creates a 'ioexec' function that runs a shell command and returns a table you can store
    - Example: Prints all the .lua files under a directory
"""

```
local ttbFILE = ioexec('find /sdcard/qlua5 -name "*.lua" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)
```

- [def_printio]
- This creates a 'printio' function that runs printiv on the ioexec table
    - Example: printio('ls /storage')

AndroidQLua\MxClasses LoadFile

```
--[under folder /sdcard/qlua5]
--This file can be run by the QLua command "LoadFile" because it uses the Load function instead of the LoadString function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) load(table.concat(ur_table, "\\r"))() end'}
load(table.concat(def_tcompile, "\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  load(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)

AndroidQLua\MxClasses Require Program Module

```
--[under folder /sdcard/qlua5]
--Create subdir share/5.3
--Put in a copy of def.lua
--This file can be run by the QLua command "require" because it uses the LoadString function instead of the Load function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) loadstring(table.concat(ur_table, "\\r"))() end'}
loadstring(table.concat(def_tcompile, "\\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  loadstring(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
--[[
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)
--]]

AndroidQLua\Source Code Editor

"""
[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icons]
- Click button New File (looks like a page with a Plus sign) -> Opens dialog

- [New file dialog]
- Click option Blank file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Enter some text

- [Bottom bar]
- Click button Save (looks like a 3.5" floppy disk)

[SDCard file list]
- Note: The file gets saved in the folder /sdcard/qlua5

AndroidScreenshot

<<glbl_article_list>>

AndroidScreenshot\Screenshot Easy

"""
[Google Play Store app]
- Install app Screenshot Easy by Ice Cold Apps
- Note: Contains ads

AndroidVNC

<<glbl_article_list>>

AndroidVNC\RealVNC remote control Windows O/S

"""
Windows O/S

[https://www.realvnc.com/en/connect/download/viewer/windows/]
- Install app VNC Connect for Windows

[VNC Connect for Windows app]
- Connects to login
- Note: Allows connection by RealVNC's VNC Viewer app on Android O/S

Android O/S

[Google Play Store]
- Install app VNC Viewer by RealVNC Limited

[VNC Viewer app]
- Connects to login
- [Alt tab]
- Use Ctrl-Esc to get to the Windows Start Menu and the Task Bar to change windows

AndroidVNC\Remote Control Android Device

"""
Install app AnyDesk by AnyDesk Software GmbH
- https://play.google.com/store/apps/details?id=com.anydesk.anydeskandroid&hl=en_US&gl=US

Install on both Android devices
- The other installed devices will show when connected to the same WiFi network
- Automatically figures out how to use the controlling Android device's touch screen

AndroidWebDav

<<glbl_article_list>>

AndroidWebDav\BestDAV

"""
Access files on Android device from a networked Windows computer

[Andrdoid OS]
- [Google Play Store]
- Install app WebDAV Server - BestDAV
- - Free or Pro edition

[WebDAV Server]
- [Main page, top bar]
- Note: Folders not listed under the "Folders" button automatically has read-only access via WebDav
- Click button Settings -> nav
- [Settings page]
- Website Home Directory = /storage
- [Main page, bottom bar]
- Click button Start Server
- Note: The server's network URL starts with "http://" and ends with ":8080"
- - Sample = http://192.168.0.15:8080

[Windows computer]
- [browser]
- Address = http://192.168.0.15:8080
- Click link Get the file list -> nav
- Note: The directory shows the "external" SD Card name (if any) and "enc_emulated"
- To see the "internal" /sdcard folder on the android device,
- - Click link "enc_emulated" -> /_dir.cgi?dir=%2Fenc_emulated
- - Edit the address to say /_dir.cgi?dir=%2Femulated/0

- [Windows Explorer]
- Address = \\192.168.0.15@8080\DavWWWRoot
- Note: The directory shows the "external" SD Card name (if any) and "emulated", "enc_emulated", and "self"
- To see the "internal" /sdcard folder on the android device,
- - Click link "emulated" -> http://192.168.0.15:8080/emulated
- - Edit the address to say http://192.168.0.15:8080/emulated/0

btn Delete Cards

<$button>
<$list filter="[tag[ARTICLE]] [tag[IMG]]"><$action-deletetiddler $tiddler=<<currentTiddler>> /></$list>
Del ARTICLE and IMG cards
</$button>

Card filter

\define tag_button(ur_field, ur_tag_name)
<$button>
<$action-setfield $tiddler="$ur_field$" text="$ur_tag_name$"/>
<$action-navigate $to="Tag pairs"/>
<<tag-pill "$ur_tag_name$">>
</$button>
\end

{{ext TW Return}}

<$list variable=on_twcard filter="[<tv-config-toolbar-icons>!match[no]]">
<$button>
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/tag_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/text_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/text_input_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
Clear filters
</$button><br>

Text search: <$edit-text tiddler="$:/state/popup/text_input_e1" field=text default="" placeholder="[Type to search for text 1]" autoHeight=yes tag=input/>
<$edit-text tiddler="$:/state/popup/text_input_e2" field=text default="" placeholder="[Type to search for text 2]" autoHeight=yes tag=input/>
<$button>
<$action-setfield $tiddler="$:/state/popup/text_e1" text={{$:/state/popup/text_input_e1}}/>
<$action-setfield $tiddler="$:/state/popup/text_e2" text={{$:/state/popup/text_input_e2}}/>
Search text
</$button><br>

<$list variable=text_prefix_e1 filter="[[$:/state/popup/text_e1]get[text]else[]]">
<$list variable=text_lowercase_e1 filter="[<text_prefix_e1>lowercase[]]">
<$list variable=text_prefix_e2 filter="[[$:/state/popup/text_e2]get[text]else[]]">
<$list variable=text_lowercase_e2 filter="[<text_prefix_e2>lowercase[]]">
<$list variable=tag_prefix_e1 filter="[[$:/state/popup/tag_e1]get[text]uppercase[]else[]]">
<$list variable=count_any_input filter="[<text_prefix_e1>] [<text_prefix_e2>] [<tag_prefix_e1>] +[each:value[]!match[]count[]]">

<$list variable=tag_list filter="[tags[]each:value[]!prefix[$:]sort[]]">
<$list variable=all_caps_taglist filter="[<tag_list>uppercase[]]">
<$list variable=filter_all_capslist filter="[<tag_list>!match<all_caps_taglist>]">
<$list variable=card_count filter="[tag<tag_list>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>count[]!match[0]]">@@white-space:nowrap;<$macrocall $name=tag_button ur_field="$:/state/popup/tag_e1" ur_tag_name=<<tag_list>> /> ( <<card_count>> )@@
</$list><!--card_count-->
</$list><!--filter_all_capslist-->
</$list><!--all_caps_taglist-->
</$list><!--tag_list
-->

<$list variable=filter_any_input filter="[<count_any_input>!match[0]]">
<$list variable=tag_e1 filter="[search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>tags[]each:value[]!prefix[$:]sort[]]">
<$list variable=all_caps_tage1 filter="[<tag_e1>uppercase[]]">
<$list variable=filter_all_capse1 filter="[<tag_e1>!match<all_caps_tage1>]">
<$list variable=filter_prefix_e1 filter="[<all_caps_tage1>prefix<tag_prefix_e1>]">
<$list variable=card_count filter="[tag<tag_e1>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>count[]]">
<$list variable=filter_card_found filter="[<card_count>!match[0]]">
<$macrocall $name=tag_button ur_field="$:/state/popup/tag_e1" ur_tag_name=<<tag_e1>> />

<$list variable=link_title filter="[tag<tag_e1>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>]">

<<<
<$link to=<<link_title>> /> (<$list variable=disp_tag filter="[<link_title>tags[]sort[]]"> <<disp_tag>> </$list>)

<$list variable=filter_anytext_e1 filter="[<text_prefix_e1>!match[]]">
<$list variable=found_leadingtext_e1 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e1>butlast[]]">

* <$list variable=sample_leadingtext_e1 filter="[<found_leadingtext_e1>split[ ]last[7]join[ ]]">
<$text text=<<sample_leadingtext_e1>> />
''<$text text=<<text_lowercase_e1>> />''
</$list><!--sample_leadingtext_e1-->
<br>
</$list><!--found_leadingtext_e1-->
<$list variable=found_trailingtext_e1 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e1>butfirst[]]">

* <$list variable=sample_trailingtext_e1 filter="[<found_trailingtext_e1>split[ ]first[7]join[ ]]">
''<$text text=<<text_lowercase_e1>> />''
<$text text=<<sample_trailingtext_e1>> />
</$list><!--sample_trailingtext_e1-->
</$list><!--found_trailingtext_e1-->
</$list><!--filter_anytext_e1
-->

<$list variable=filter_anytext_e2 filter="[<text_prefix_e2>!match[]]">
<$list variable=found_leadingtext_e2 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e2>butlast[]]">

* <$list variable=sample_leadingtext_e2 filter="[<found_leadingtext_e2>split[ ]last[7]join[ ]]">
<$text text=<<sample_leadingtext_e2>> />
''<$text text=<<text_lowercase_e2>> />''
</$list><!--sample_leadingtext_e2-->
<br>
</$list><!--found_leadingtext_e2-->
<$list variable=found_trailingtext_e2 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e2>butfirst[]]">

* <$list variable=sample_trailingtext_e2 filter="[<found_trailingtext_e2>split[ ]first[7]join[ ]]">
''<$text text=<<text_lowercase_e2>> />''
<$text text=<<sample_trailingtext_e2>> />
</$list><!--sample_trailingtext_e2-->
</$list><!--found_trailingtext_e2-->
</$list><!--filter_anytext_e2
-->

<<<
</$list><!--link_title-->
</$list><!--filter_card_found-->
</$list><!--card_count-->
</$list><!--filter_prefix_e1-->
</$list><!--filter_all_capse1-->
</$list><!--all_caps_tage1-->
</$list><!--tag_e1-->
</$list><!--filter_any_input-->
</$list><!--count_any_input-->
</$list><!--tag_prefix_e1-->
</$list><!--text_lowercase_e2-->
</$list><!--text_lowercase_e1-->
</$list><!--text_prefix_e2-->
</$list><!--text_prefix_e1-->
</$list><!--on_twcard-->

[[Search All Code |View All Code]]

[[___|Recent Entries]]

ChromeBrowser

<<glbl_article_list>>

ChromeBrowser\Browse Local Folders

"""
Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome

[Google Chrome app]
- [Windows O/S]
- Navigate to file:///C:/
- [Android O/S]
- Navigate to file:///sdcard/

- [Directory list]
- Select which sub-folder you want to bookmark
- [Navigation bar, Top-right icons]
- Click button Bookmark Page (looks like a star shape) -> Opens dialog
- [Bookmark Added dialog]
- Name = UrShortName
- Click button Done -> Closes dialog
- [Navigation bar]
- Address = UrShortName -> Shows suggestions
- [Suggestion list]
- Select the suggested link -> Navigates page

ChromeBrowser\Command Line Options

"""
The command line options are usually two hyphens followed by a keyword

- Note: The incognito option starts the browser with an open Incognito window
"""

```
–incognito
```

"""
- Note: Google Chrome Portable has these parameters automatically included when calling the Chrome.exe program.
"""

```
–user-data-dir="%TEMP%"
–disk-cache-dir="%TEMP%\GoogleChromePortable\Cache"
```

"""
To override the user data and all the cache directories:

- Find the INI file in the PortableApp sub-directory
"""

```
GoogleChromePortable\Other\Source\GoogleChromePortable.ini
```

"""
- Copy it to the program main directory
"""

```
GoogleChromePortable\GoogleChromePortable.ini
```

"""
- [Edit the file]
- CacheInTemp = false
- Save file
- Note: When you restart Google Chrome Portable, cached files will be stored under the program's folder
"""

```
C:\TJBF\zPortableInstalls\Chrome\Data\profile\Default\*Cache\
```

ChromeBrowser\Turn off Chrome spell check highlighting

"""
[Google Chrome app]
- [Top-right icons]
- Click the three-dots menu, option Settings -> Navigates page
- [Settings page[
- search for Language -> Filters results
- [Languages section]
- checkbox Spell check = clear -> Chrome will not highlight spelling errors

Code Samples

{{ext TW Return}}

<<list-links filter:"[tag[DOC]sort[title]]">>

[[___|Recent Entries]]

css alternating-rows

.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}

DivPop btn

<$list variable=cur_card filter="[all[current]]">
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=<<cur_card>>/>
<$action-sendmessage $message="tm-close-tiddler" $param="pop_right"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{DivPop.svg}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text="Popup over Sidebar"/></span>
</$list>
</$button>
</$list>

DivPop glbl

<$list variable=cur_divpop_card filter="[{$:/state/popup/DivPopTitle}is[tiddler]]">
<div style="
position: fixed;
top: 0px;
right: 0px;
width: 350px;
border: 3px solid;
background: white;
bottom: 0%;
">
<div style="overflow-y: scroll; height: 100%;">
<$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
close
</$button>
&nbsp;&nbsp;&nbsp;<$reveal type="match" state="$:/state/popup/$ur_pk$" text="show"><$button set="$:/state/popup/$ur_pk$" setTo="hide">show</$button>&nbsp;&nbsp;&nbsp;<$link to=<<cur_divpop_card>> ><<cur_divpop_card>>
</$link>
<$list variable=cur_text filter="[<cur_divpop_card>get[text]]">
<$codeblock code=<<cur_text>> /></$list>
</$reveal>
<$reveal type="nomatch" state="$:/state/popup/$ur_pk$" text="show"><$button set="$:/state/popup/$ur_pk$" setTo="show">code</$button>&nbsp;&nbsp;&nbsp;<$link to=<<cur_divpop_card>> ><<cur_divpop_card>>
</$link>
<$tiddler tiddler=<<cur_divpop_card>> >
<$transclude mode="block" />
</$tiddler>
</$reveal>
</div>
</div>
</$list>

Excel VBA

<<glbl_article_list>>

Excel VBA\Get Worksheet

```
Dim wksDATA As Worksheet
Set wksDATA = Application.ActiveSheet
wksDATA.Cells(2,2).Value = "Hi"

'Press F5 to run the macro
'Note: Cell B2 says "Hi"

Excel VBA\New Macro

"""
[Microsoft Excel application]
- [Ribbon menus]
- View menu, option Record Macro -> Starts recording
- View menu, option Stop Recording -> Stops recording
- View menu, option Macros -> Opens dialog

[Macro list]
- Click button Edit Macro -> Opens window

[VBA Editor]
- You can change the name of the macro and add commands
- Close the editor

[Microsoft Excel application]
- Save the file as a Macro-Enabled workbook (mwb)

Excel VBA\Power Exponent

"""
Make sure you put a space between the power operator (^) and the numbers

- CalcResult = 2^5
- Note: This gives a compilation error on 64-bit Excel

- CalcResult = 2 ^ 5
- Note: CalcResult = 32

ext ALAorg Citations bookmarklet

http://www.ala.org/tools/article/ala-techsource/%E2%80%9Ccitethis%E2%80%9D-building-javascript-bookmarklet-creates-citations-sharing-web

ext Apple.com Safari Meta tags

https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html

ext CodeAcademy DocType

https://discuss.codecademy.com/t/why-we-type-before-doctype-what-is-the-role-of-in-doctype-html/60880/3

ext DeveloperSettings HTM

VBNet_Project\DeveloperSettings\Developer Settings App.html

ext DeveloperSettings ZIP

VBNet_Project\DeveloperSettings\DeveloperSettings.zip

ext Empty Wiki Setup

TW Project\Empty Wiki\Empty Wiki.htm

ext FileFormat.Info UnicodeInput

https://www.fileformat.info/tool/unicodeinput/index.htm

ext FileFormat.Info UnicodeInput.ZIP

https://www.fileformat.info/tool/unicodeinput/unicodeinput.zip

ext GitHub LukeHorvat Computed Style to Inline

https://github.com/lukehorvat/computed-style-to-inline-style

ext GoogleDevelopers FullScreen web app

https://developers.google.com/web/fundamentals/native-hardware/fullscreen/

ext HTML.com DocType

https://html.com/tags/doctype/

ext JavaScript Closures

http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html

ext JavaScript Strict Mode

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

ext JavaScript This Parameter

http://blog.niftysnippets.org/2008/03/mythical-methods.html

ext JTFAssociates MOTW

https://jtfassociates.com/using-the-mark-of-the-web-motw/

ext MathiasBynens Rel Icon

https://mathiasbynens.be/notes/rel-shortcut-icon

ext MetaTags.org Generator

https://www.metatags.org/all-meta-tags-overview/meta-name-generator/

ext Microsoft DotNet Char ConvertToUTF32

https://docs.microsoft.com/en-us/dotnet/api/system.char.converttoutf32?view=net-5.0#System_Char_ConvertToUtf32_System_String_System_Int32_

ext Microsoft RemoteDesktop Enable

https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-allow-access

ext Mozilla.org META tags

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name

ext MozillaDeveloper CSS Comment

https://developer.mozilla.org/en-US/docs/Web/CSS/Comments

ext MozillaDeveloper Strict mode

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

ext MxBase Classes

VBNet_Project/MxBase/MxBase%20Classes.html

ext Project Check app

TW Project\Checkapp\Checkapp.htm

ext PSU.edu LangTag

https://accessibility.psu.edu/foreignlanguages/langtaghtml/

ext Regexp Filter with brackets

https://tiddlywiki.narkive.com/T5403O4p/tw5-regexp-for-matching-a-tag-tiddlytweeter#post7

ext Regular Expression Quantifiers

https://www.rexegg.com/regex-quantifiers.html

ext Roman to Decimal ZIP

VBNet_Project\Examples\Roman_To_Decimal.zip

ext Shuffle List Entries

TiddlyWiki_Code\Snapshot\mklauber TWPlugin Shuffle.txt.html

ext SitePoint Exports Node.JS

https://www.sitepoint.com/understanding-module-exports-exports-node-js/

ext SO.com RunTime Net 4.5

https://stackoverflow.com/questions/8517159/how-do-i-detect-at-runtime-that-net-version-4-5-is-currently-running-your-code

ext SQLite Blob text

https://stackoverflow.com/questions/15366594/convert-hex-to-text-using-sqlite

ext SQLite DB Browser

https://sqlitebrowser.org/dl/

ext SQLite Language functions

https://sqlite.org/lang_corefunc.html

ext SQLite schema information

https://stackoverflow.com/questions/6460671/sqlite-schema-information-metadata

ext SQLite Top 5 Records

https://stackoverflow.com/questions/2728999/how-to-get-top-5-records-in-sqlite

ext StackOverflow CSS location

https://stackoverflow.com/questions/1642212/whats-the-difference-if-i-put-css-file-inside-head-or-body

ext StackOverflow Hide Parent Show Child tag

https://stackoverflow.com/questions/12956937/display-html-child-element-when-parent-element-is-displaynone

ext StackOverflow Meta UA-Compatible

https://stackoverflow.com/questions/6771258/what-does-meta-http-equiv-x-ua-compatible-content-ie-edge-do#:~:text=The%20X%2DUA%2DCompatible%20meta%20tag%20allows%20web%20authors%20to,meta%20tag%20in%20certain%20circumstances.

ext Tiddly Wiki Home Button source code

https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/PageControls/home.tid

ext TiddlyWiki Save Button source code

https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/PageControls/savewiki.tid

ext TiddlyWiki TopBar Menu

https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/TopRightBar/menu.tid

ext TW Addon Text Replace

TiddlyWiki_Code\AddOns\Text Replace Bar.htm

ext TW Create Javascript Plugin

https://sudonull.com/post/97468-How-to-write-a-plugin-for-TiddlyWiki

ext TW Features

TiddlyWiki_Code\Features\TW Features.htm

ext TW JS Pretty

TW Project\JS_Pretty\TW JS Pretty.htm

ext TW Manual

TiddlyWiki_Code\Snapshot\TheBook - The TiddlyWiki Manual.txt.html

ext TW Return

\define TW_Return(ur_url, ur_link_title)
<div style="float:right"><a href="$ur_url$"> ($ur_link_title$)</a></div>
\end
<$list variable=found_index filter="[{$:/info/url/full}split[/]count[]subtract[1]]">
<$list variable=skip_html filter="[<tv-config-toolbar-icons>match[no]]">
<$list variable=return_url filter="[{$:/info/url/full}split[/]butfirst<found_index>first[]split[.html]join[.htm]addprefix[src/]]">
<$macrocall $name=TW_Return ur_url=<<return_url>> ur_link_title="TiddlyWiki view of website" />
</$list><!--found_html-->
</$list><!--skip_html-->
<$list variable=found_html filter="[<tv-config-toolbar-icons>!match[no]]">
<$list variable=return_url filter="[{$:/info/url/full}split[/]butfirst<found_index>first[]split[.html]join[.htm]split[.htm]join[.html]addprefix[../]]">
<$macrocall $name=TW_Return ur_url=<<return_url>> ur_link_title="Static HTML view of website" />
</$list>
</$list><!--found_html-->
</$list><!--found_index-->

ext TW Snapshot Review

TiddlyWiki_Code\Snapshot\Browse Code tiddlywiki_v5d01d23pre-release.htm

ext TW Snapshot v5d01d23 empty

TW Project\Snapshot\tw_empty_v5d01d23.html

ext TW Snapshot v5d01d23 main-site

TW Project\Snapshot\tiddlywiki_v5d01d23_main-site.html

ext TW Snapshot v5d01d23 pre-release

TW Project\Snapshot\tiddlywiki_v5d01d23_pre-release.html

ext TW Snapshot v5d01d23 update

TW Project\Snapshot\tiddlywiki_v5d01d23_update.html

ext Unicode Block 00-Basic Latin

https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)

ext Unicode Block 01-Latin Supplement

https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)

ext Unicode Block Planes

https://en.wikipedia.org/wiki/Plane_(Unicode)

ext Unicode Character Database

http://www.unicode.org/Public/UCD/latest/

ext Unicode Code Block List

https://en.wikipedia.org/wiki/Unicode_block

ext VBNetScript.EXE

VBNet_Project\VBNetscript\VBNetScript_EXE.zip

ext VBNetScript.SLN

VBNet_Project\VBNetscript\VBNetScript_Project.zip

ext W3.org HTML401 Meta

https://www.w3.org/TR/html401/struct/global.html#h-7.4.4

ext W3.org HTML401 Profiles

https://www.w3.org/TR/html401/struct/global.html#profiles

ext W3Schools DocType

https://www.w3schools.com/tags/tag_doctype.asp

ext W3Schools Head tag

https://www.w3schools.com/tags/tag_head.asp

ext W3Schools Meta HTTP-EQUIV

https://www.w3schools.com/tags/att_meta_http_equiv.asp

ext W3Schools NoScript tag

https://www.w3schools.com/tags/tag_noscript.asp

ext WestWindCom Net Core Runtime

https://weblog.west-wind.com/posts/2018/Apr/12/Getting-the-NET-Core-Runtime-Version-in-a-Running-Application

ext WHATWg.org Link Icon

https://html.spec.whatwg.org/multipage/links.html#rel-icon

ext Wiki Move HTM

VBNS_Project\Wiki_Move\Wiki Move HTM.htm

ext Windows Alt-Numpad Unicode

https://conemu.github.io/en/AltNumpad.html

ext Windows Environment Variable List

https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables#bkmk-1

ext Windows Terminal Unicode Support

https://devblogs.microsoft.com/commandline/introducing-windows-terminal/

ext WindowsCLI Unicode Support

https://www.generacodice.com/en/articolo/203149/How-to-use-unicode-characters-in-Windows-command-line

FFMPeg

<<glbl_article_list>>

FFMPeg\Extract Captions file

```
chcp 65001
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" "C:\UrPath\UrFile.srt"
pause

FFMPeg\Extract JPG files

"""
[ffmpeg.exe command-line options]
- `-ss 05:00 -t 10:00` means start at 5min and end 10min later at 15min
- `-r 1` means 1 frame per second
- `-r 0.25` means 1 frame every 4 seconds
- `-r 0.083` means 1 frame every 12 seconds, or 5 frames per minute, 50 frames out of every ten minutes, or 300 frames every hour

- IrfanView can create a portrait contact sheet with 5 columns, representing one min of video per row, 10 rows per page showing 10 minutes of video
- IrfanView can create a landscape contact sheet with 7 columns is one 3 min per 2 rows, 7 rows per page showing 10.5 minutes of video, two pages showing 21 minutes

- Open on thumbnail image with IrfanView, select File menu Thumbnails option
- Select all files in the folder, select File menu Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

"""

```
chcp 65001
rem -ss 05:00 -t 10:00 means start at 5min and end 10min later at 15min
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" -r 0.083 -s 320x180 "UrPath\UrSubdir\output_%%04d.jpg"


Font Size

<$list variable=cur_entry filter="[all[tiddlers]!suffix[.js]!suffix[.css]!match[$:/core]!prefix[$:/config/]!prefix[$:/DefaultTiddlers]!prefix[$:/Import]!match[$:/isEncrypted]!prefix[$:/language/]!prefix[$:/theme]!prefix[$:/temp/]!prefix[$:/status/]!match[$:/StoryList]!match[$:/HistoryList]!match[$:/SiteTitle]!match[$:/SiteSubtitle]!prefix[$:/state/]count[]]">
Specific prefix filter: <<cur_entry>> cards
</$list>

<$list variable=cur_entry filter="[all[tiddlers]!is[system]] [prefix[$:/positivesigner]] +[count[]]">

Non-system plus system PositiveSigner filter: <<cur_entry>> cards
</$list>


<$button>
<$list variable=cur_card filter="[!is[system]!prefix[Draft of]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[append[COPY]]"/>
</$list>
Append COPY tag to all non-system cards
</$button><br>

<$button>
<$list variable=cur_card filter="[tag[COPY]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[remove[COPY]]"/>
</$list>
Remove COPY tag from all cards
</$button><br>


<$button>
{{keyboard action FontLarge}}
Big Font
</$button>

<$button>
{{keyboard action FontNormal}}
Normal Font
</$button>

[[Panel]]

!!Cards where has[tags] does not work

<$list variable=cur_card filter="[is[tiddler]]">
<$list variable=has_tags_test filter="[<cur_card>!has[tags]count[]] [<cur_card>has[tags]count[]] +[sum[]match[0]]">

<$link to=<<cur_card>> />
</$list><!--has_tags_test-->
</$list><!--cur_card-->

!!Cards with no tags

<$list variable=cur_card filter="[!is[system]is[tiddler]!has[tags]!prefix[Draft of]!prefix[$:/state/]!prefix[$:/library/]!prefix[$:/boot/]!prefix[$:/temp/]!match[$:/core]!match[$:/Import]!match[$:/isEncrypted]!match[$:/SiteSubtitle]!match[$:/SiteTitle]!prefix[$:/status/]!match[$:/StoryList]!match[$:/HistoryList]!match[$:/theme]!match[$:/themes/tiddlywiki/snowwhite]!match[$:/themes/tiddlywiki/vanilla]]">
<$list variable=has_parent_card filter="[<cur_card>split[\]count[]match[1]]">

<$link to=<<cur_card>> />
</$list><!--has_parent_card-->

<$list variable=has_parent_card filter="[<cur_card>split[\]count[]!match[1]]">
<$list variable=parent_card_exists filter="[<cur_card>split[\]first[]!is[tiddler]]">

<$link to=<<cur_card>> />
</$list><!--parent_card_exists-->
</$list><!--has_parent_card-->
</$list><!--cur_card-->


[[parm SkipSaveExportHTML]]

[[btn Delete Cards]]

GitCLI

<<glbl_article_list>>

GitCLI\Checkout hash

```
@echo off
SET ur_repo=
SET ur_branch=
"C:\UrPath\git.exe" -C %ur_repo% checkout -b test-branch %ur_branch%

rem Use GitHub Desktop to delete the branch

GitHubDesktop

<<glbl_article_list>>

GitHubDesktop\Git executable

"""
When GitHub Desktop is installed, the Git.exe program is placed in the %APPDATA% folder. There is one sub-directory for each version of Git that has been downloaded. Look for the latest version-numbered folder.
"""

```
C:\Users\UrUser\AppData\Local\GitHubDesktop\app-UrVersion
```

"""
Under the app-UrVersion folder, find the Git.exe program
"""

```
app-UrVersion\resources\app\git\cmd\git.exe

GoogleContacts

<<glbl_article_list>>

GoogleContacts\Export as CSV

"""
[https://contacts.google.com/]
- [Left-side menu]
- Click button Export -> Opens dialog
- Export contacts = Contacts (total count)
- Export as = Google CSV
- Click button Export -> Downloads file, Closes dialog

[CSV file]
- Header fields =
"""

```
Name
Given Name
Additional Name
Family Name
Yomi Name
Given Name Yomi
Additional Name Yomi
Family Name Yomi
Name Prefix
Name Suffix
Initials
Nickname
Short Name
Maiden Name
Birthday
Gender
Location
Billing Information
Directory Server
Mileage
Occupation
Hobby
Sensitivity
Priority
Subject
Notes
Language
Photo
Group Membership
E-mail 1 - Type
E-mail 1 - Value
E-mail 2 - Type
E-mail 2 - Value
Phone 1 - Type
Phone 1 - Value
Phone 2 - Type
Phone 2 - Value
Address 1 - Type
Address 1 - Formatted
Address 1 - Street
Address 1 - City
Address 1 - PO Box
Address 1 - Region
Address 1 - Postal Code
Address 1 - Country
Address 1 - Extended Address
Organization 1 - Type
Organization 1 - Name
Organization 1 - Yomi Name
Organization 1 - Title
Organization 1 - Department
Organization 1 - Symbol
Organization 1 - Location
Organization 1 - Job Description
Relation 1 - Type
Relation 1 - Value
Website 1 - Type
Website 1 - Value
```

- Header line =

```
Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initials,Nickname,Short Name,Maiden Name,Birthday,Gender,Location,Billing Information,Directory Server,Mileage,Occupation,Hobby,Sensitivity,Priority,Subject,Notes,Language,Photo,Group Membership,E-mail 1 - Type,E-mail 1 - Value,E-mail 2 - Type,E-mail 2 - Value,Phone 1 - Type,Phone 1 - Value,Phone 2 - Type,Phone 2 - Value,Address 1 - Type,Address 1 - Formatted,Address 1 - Street,Address 1 - City,Address 1 - PO Box,Address 1 - Region,Address 1 - Postal Code,Address 1 - Country,Address 1 - Extended Address,Organization 1 - Type,Organization 1 - Name,Organization 1 - Yomi Name,Organization 1 - Title,Organization 1 - Department,Organization 1 - Symbol,Organization 1 - Location,Organization 1 - Job Description,Relation 1 - Type,Relation 1 - Value,Website 1 - Type,Website 1 - Value
```

- Sample data 1

```
.me,.me,,,,,,,,,,,,,,,,,,,,,,,,,,,Imported 8/5/16 ::: * myContacts,,,,,Mobile,5554443333 ::: 16665554444,,,,,,,,,,,,,,,,,,,,,,,
```

- Sample data 2

```
UrContactName,UrContactFirstName,,UrContactLastName,,,,,,,,,,,,,,,,,,,,,,,,,* myContacts,,,,,Mobile,(444) 333-2222,,,,,,,,,,,,,,,,,,,,,,,
```

GoogleGmail

<<glbl_article_list>>

GoogleGmail\Export as MBOX

"""
[https://takeout.google.com/]
- [Products section]
- Click link Deselect All
- [Mail section]
- checkbox = set
- [End of Page section]
- Click button Next Step -> Navigates section
- [Choose file type, frequency & destination]
- Frequency = Export once
- File type = .zip
- File size = 2 GB
- Click button Create Export -> Navigates section
- [Export Progress]
- Note: Google is creating a copy of files from Mail. This process can take a long time (possibly hours or days) to complete. You'll receive an email when your export is done.

[https://mail.google.com/]
- [Message with title "Archive of Google data requested"]
- Note: You can ignore the message or click the link to verify it was you
- [Message with title "Your Google data is ready to download"]
- Click button Download Your Files -> Opens tab

[Google Takeout form]
- Re-enter your password
- [Record where Export = Mail]
- Note: The size of the export file is also in the Export column
- Click button Download -> Downloads file
- Note: The file may take a long time to download depending on your internet connection and the size of the file

[ZIP file]
- Extract the ZIP file to a folder

[Takeout folder]
- Open the archive_browser.html -> Opens browser

[Archive Browser page]
- [File Formats tab]
- Note: An mbox is a way of storing mail messages and is supported by common mail clients like Microsoft Outlook, Mozilla Thunderbird, and Apple's Mail program. These files are most easily opened by a dedicated mail client like those listed above

[Takeout\Mail folder]
- [All mail Including Spam and Trash.mbox]
- Use Mozilla Thunderbird to read the MBOX file
- OR Split this file into smaller text files... [[somehow |VBNetCode\Copy File Lines]]
- Format:

Record Start = Leading "From " <- Including the space
Tags = "WordsWithoutSpaces:" <- no spaces in tag name
Tag continuation values = " Every Line With Leading Space Or Tab After Tag Name"
Email Content = "First line that is not a tag or tag continuation -> through last line before next leading " "From "

GoogleGmail\MBOX file parsing test

```
start "" "%~dp0\MxClasses\VBNetScript.exe" /path=%0 & exit
MxClasses\MxBaseEc12.vb
RetVal = Mx.Want.TextFile_Split_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.TextFile_Split_errhnd
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub TextFile_Split(ret_message As Strap)
			Dim tabchr = CHR(9)
			Dim flnDATA = FileNamed().d("C:\Users\Dad\Downloads\Takeout\Mail\All mail Including Spam and Trash.mbox")
			Dim intLINE_COUNT = 0
			Dim sdaPREFIX_SKIPPED = New Sdata
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), False, gUTF8_FileEncoding)
				Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
				    Dim bolINCLUDE_INDENTED_LINES = False
					Dim bolHTML_TEXT = False
					Dim bolPLAIN_TEXT = False
					Dim bolSKIP_TEXT = False
					While stmDATA.EndOfStream = False
						Dim strLINE = stmDATA.ReadLine()
						If strLINE.Length = 0 Then
						
						ElseIf Left(strLINE, 5) = "From " AndAlso
						  Len(strLINE) = 59 Then
						    bolINCLUDE_INDENTED_LINES = False
							bolHTML_TEXT = False
							bolPLAIN_TEXT = False
							bolSKIP_TEXT = False
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine(strLINE)
							intLINE_COUNT += 1
						
						ElseIf bolSKIP_TEXT Then
						
						ElseIf bolPLAIN_TEXT Then
							If strLINE.Trim.Length > 0 Then
								Dim bolCUR_HTML = False
								Dim intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									bolCUR_HTML = True
									
									End If
								
								If Left(strLINE, 16) = "X-Attachment-Id:" OrElse
								  Left(strLINE, 32) = "Content-Transfer-Encoding:base64" Then
									bolSKIP_TEXT = True
									
									End If 'strLINE
								
								If bolHTML_TEXT = False Then
									stmOUT_FILE.WriteLine(strLINE)
									intLINE_COUNT += 1
								
								ElseIf bolCUR_HTML Then
									Dim strTEXT = strLINE
									While intFOUND_SPRTR > 0
										Dim strPREFIX = Mid(strTEXT, 1, intFOUND_SPRTR - 1)
										Dim strTAG = Mid(strTEXT, intFOUND_SPRTR)
										intFOUND_SPRTR = InStr(strTAG, ">")
										If intFOUND_SPRTR = 0 Then
											strTEXT = strPREFIX
										
										Else
											strTEXT = strPREFIX & Mid(strTAG, intFOUND_SPRTR + 1)
											intFOUND_SPRTR = InStr(strTEXT, "<")
											
											End If 'intFOUND_SPRTR
										
										End While 'intFOUND_SPRTR
									
									If strTEXT.Trim.Length > 0 Then
										stmOUT_FILE.WriteLine(strTEXT)
										intLINE_COUNT += 1
										
										End If
									
									End If 'intFOUND_SPRTR
									
								End If 'strLINE
							
						ElseIf (Left(strLINE, 1) = s OrElse Left(strLINE, 1) = tabchr) AndAlso
						  bolINCLUDE_INDENTED_LINES Then
							'stmOUT_FILE.WriteLine(strLINE)
							'intLINE_COUNT += 1
						    
						Else 'strLINE
						    bolINCLUDE_INDENTED_LINES = False
							Dim strPREFIX = mt
						    Dim intFOUND_SPRTR = InStr(strLINE, ":")
							If intFOUND_SPRTR > 0 Then
							    strPREFIX = Mid(strLINE, 1, intFOUND_SPRTR)
								If InStr(strPREFIX, tabchr) > 0 OrElse
								  InStr(strPREFIX, s) > 0 Then
									strPREFIX = mt
									
									End If
								
								End If
							
							If strPREFIX = "Content-Type:" OrElse
							  strPREFIX = "Subject:" OrElse
							  strPREFIX = "To:" OrElse
							  strPREFIX = "Date:" OrElse
							  strPREFIX = "From:" Then
								bolINCLUDE_INDENTED_LINES = True
								stmOUT_FILE.WriteLine(strLINE)
								intLINE_COUNT += 1
							
							ElseIf Right(strPREFIX, 1) = ":" Then
								bolINCLUDE_INDENTED_LINES = True
								If sdaPREFIX_SKIPPED.Contains(strPREFIX) = False Then
									sdaPREFIX_SKIPPED.d(strPREFIX)
									
								    End If
							
							ElseIf strPREFIX = "" Then
							    bolPLAIN_TEXT = True
								intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									
									End If
								
								End If 'strPREFIX
							
							End If 'strLINE
						
						If intLINE_COUNT >= 100000 Then
							Exit While
							
							End If
						
						End While 'stmDATA
					
					End Using 'stmDATA
				
				End Using 'stmOUT_FILE
			
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("PREFIX_SKIPPED.TXT"), False, gUTF8_FileEncoding)
				Call sdaPREFIX_SKIPPED.Sort()
				For Each strENTRY In sdaPREFIX_SKIPPED
					stmOUT_FILE.WriteLine(strENTRY)
					
					Next strENTRY
				
				End Using 'stmOUT_FILE

			ret_message.Clear.d(intLINE_COUNT.ToString)
			
			End Sub 'TextFile_Split

        Public Shared Function TextFile_Split_errhnd() As Strap
            Dim stpRET = Strapd()
            TextFile_Split_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call TextFile_Split(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'TextFile_Split_errhnd
    End Class 'Want
End Namespace 'Mx

GooglePlay

<<glbl_article_list>>

GooglePlay\Share purchased apps with another account

"""
[Play Store app]
- [Top-left icon]
- Click the three-lines menu, option `Family Library` -> Navigates page
- Note: There are two Sections
- - `Added by [Other]`
- - `Added by you`

If the purchased app you want to share is not shown under the `Added by You` section, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option `My apps & games` -> Navigates page
- [Installed tab, or Library tab]
- Choose an app you purchased -> Navigates page
- [App page]
- Note: The checkbox Family Library is a toggle switch
- checkbox Family Library = set -> The app is available to all `Family` logins

If the 'Family' logins does not contain the account you want to access your shared app, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option `Account` -> Navigates page
- [Family tab]
- Click button Manage family members -> Opens dialog
- [Family dialog]
- Click button Invite family members -> Opens dialog
- [Verify CVC dialog]
- Enter your credit card number's CVC number
- Click button Verify -> Closes dialog, Opens dialog
- [Send Invitations dialog]
- Select a contact
- Click button Send

[Added Account email]
- Click the invitation link -> Navigates page
- Note: The Added Account can now use the Play Store app to install the Family Library shared app

GooglePlusCodes

<<glbl_article_list>>

GooglePlusCodes\Find a Plus Code

"""
[https://plus.codes/map/]
- [Search box, Left-side icon]
- Click the three-lines menu, option Satellite -> Refreshes window
- Click the three-lines menu, option Grid -> Refreshes window
- [Navigate to location]
- When the mouse icon is a hand, double-click to Zoom in
- Each time you click, the location will show as 8 characters, a plus sign, and two suffix characters
- - Example: 73F6C9JH+HR
- The last two Zoom levels allow you to select a single Plus Code rectangle, which has three suffix characters after the plus sign
- - Example: 73F6C9JH+HR7
- Copy the browser address bar
- - Example: https://plus.codes/73F6C9JH+HR7

- Note: You can email the page link to someone
- - They will have to turn on the satellite and / or grid options again

- Note: You can use the browser to bookmark the current page
- - Android O/S Chrome can create a desktop shortcut to the current website page (when not in Incognito mode)

- Note: The plus codes are 8 characters, a plus, and two or three suffix characters
- - The bottom of the Plus.Codes website's map only temporarily shows the three suffix characters after you click, quickly reverting to show only two suffix characters
- - You can still see all three suffix characters in the address bar

- [Bottom location code bar, Right-side icon]
- Click button Navigate (looks like a Right-Turn Only road sign) -> Navigates to Google Maps website
- Note: Android O/S Chrome app will ask to Stay On Web or Use The App
- - Click button Use The App to open the Google Maps app

HTML CSS

<<glbl_article_list>>

HTML CSS\Comment Declaration

!! HTML 5 document

* Declaration Name = `--`
* Content = unprocessed text, except for the character sequence double-hyphen close-tag ( `-->` )
* Note: HTML declarations are not tags, because the have an exclamation mark ( `!` ) before the declaration name / code
* Note: XML documents have a requirement that a double-hyphen ( `--` ) must itself be doubled ( `----` ) when used in a comment declaration, but HTML 5 has no such requirement


!! Sample code for HTML 5 Comment

```
<!-- a text editor can see the comment text -->
```


HTML CSS\Comment MOTW Declaration

!! HTML document viewed in Internet Explorer

* Comment text sequence:

<<<
* `<!--` and optional whitespace
* `saved from url=(`
* the number of characters in the URL string (including the trailing backslash)
* `)`
* the URL string
* optional whitespace and `-->`
<<<

* HTML documents viewed in Internet Explorer show a warning message due to active content, or has a specifically crafted HTML Comment Declaration that names the root URL of the website it is being hosted on
* Note: If this is for a new site, or if the domain is not known, you can use `about:internet` as a valid URL

<<ext "JTFAssociates MOTW">>

!!Sample code

```
<!-- saved from url=(0014)about:internet -->
```

HTML CSS\Compatibility Meta tags

!! Declare compatibility version of Microsoft Internet Explorer web browser

* tag name = `meta`
* `http-equiv` attr = `X-UA-Compatible`
* `content` attr = `IE=Edge` or (`IE=11`, `IE=EmulateIE11`, and similar version number pairs)
* Note: Use this tag if you need features specific to an older version of IE like IE9 or IE8
* Note: If you only support the latest browsers (IE11 and/or Edge) then this tag will not affect the web page's behavior until another version is created

<<<
Internet Explorer begins interpreting markup using the latest version. When Internet Explorer encounters the X-UA-Compatible META tag it starts over using the designated version's engine. This is a performance hit because the browser must stop and restart analyzing the content.
<<<

<<ext "StackOverflow Meta UA-Compatible">>

!! Sample code

```
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
```

<<<
`content="IE=Edge" ` mode tells Internet Explorer to display content in the highest mode available. With Internet Explorer 9, this is equivalent to IE9 mode. If a future release of Internet Explorer supported a higher compatibility mode, pages set to edge mode would appear in the highest mode supported by that version. Those same pages would still appear in IE9 mode when viewed with Internet Explorer 9.
<<<

!! Specify web application runs in full-screen mode on Apple devices

* tag name = `meta`
* `name` attr = `apple-mobile-web-app-capable`
* `content` attr = `yes`
* Note: The default behavior is to use Safari to display web content
* Note: You can determine whether a webpage is displayed in full-screen mode using the window.navigator.standalone Boolean JavaScript property

<<ext "Apple.com Safari Meta tags">>

!! Sample code

<<<
<meta name="apple-mobile-web-app-capable" content="yes" />
<<<

!! Specify the Full Screen's status bar style on Apple devices

* tag name = `meta`
* `name` attr = `apple-mobile-web-app-status-bar-style`
* `content` attr = `default`, `black`, `black-translucent`
* Note: If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar
* Note: This meta tag has no effect unless you first specify full-screen mode as described in apple-apple-mobile-web-app-capable

<<ext "Apple.com Safari Meta tags">>

!! Sample code

```
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
```

!! Leave original formatting of telephone-number formatted strings 

* tag name = `meta`
* `name` attr = `format-detection`
* `content` attr = `telephone=no`
* Note: By default, Safari on iOS detects any string formatted like a phone number and makes it a link that calls the number

<<ext "Apple.com Safari Meta tags">>

!! Sample code

```
<meta name="format-detection" content="telephone=no" />
```

!! Specify web application runs in full-screen mode on Apple devices

* tag name = `meta`
* `name` attr = `mobile-web-app-capable`
* content = `yes`
* Note: This tells the browser to launch the page fullscreen when the user has added it to the home screen
* Note: A better option is to use the Web App Manifest for Chrome, Opera, Firefox, and Samsung browsers

<<ext "GoogleDevelopers FullScreen web app">>

!! Sample code

```
<meta name="mobile-web-app-capable" content="yes"/>
```

HTML CSS\CSS Style definitions

!! Place a CSS style-sheet in the HTML document

* tag name = `style`
* `type` attr = `text/css`
* Note: The most recent versions of the HTML spec now permits the &lt;style> tag within body elements
* Note: Putting CSS in body means it is loaded later and the browser starts drawing the interface faster
* Note: Putting CSS in body can decrease page performance due to possible reflows/repaints once the browser hits styles further down in the page tree

<<ext "StackOverflow CSS location">>

!! Sample code

```
<style type="text/css">
```

!! Place a comment inside of a CSS style-sheet

* Start CSS comment text with forward-slash asterisk ( `/*` )
* End CSS comment text with asterisk forward-slash ( `*/` )

<<ext "MozillaDeveloper CSS Comment">>

!! Sample code

```
<style type="text/css">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>
```

HTML CSS\Declare document Content type


HTML CSS\DocType Declaration

!! HTML 5 document

* Declaration Name = `DOCTYPE`
* Content = `html`
* Note: HTML declarations are not tags, because the have an exclamation mark ( `!` ) before the declaration name / code
* Note: This should be the first non-whitespace characters in the document to be compliant with HTML standards
* Note: HTML5 documents don't really need a DOCTYPE as there is no HTML5 DTD for browsers to refer to, but it is used in HTML5 to make sure the browser doesn’t switch into “quirks” mode and remains in full standards mode

<<ext "W3Schools DocType">>

<<ext "HTML.com DocType">>

<<ext "CodeAcademy DocType">>

!! Sample code for HTML 5 declaration

```
<!DOCTYPE html>
```


HTML CSS\Head section

!! Set metadata values for interpreting document contents
* The &lt;head> element is a container for metadata (data about data) and is placed between the &lt;html> tag and the &lt;body> tag
* Metadata describes how to interpret and format the HTML document stored within the &lt;body> tag

<<ext "W3Schools Head tag">>

!! Sample code

```
<head>
  <title>UrTitle</title>
</head>
```

HTML CSS\Hide content

!! Hide content until user action

* CSS style name = `display`
* value = `none`
* Note: The entire tag and sub-tag structure is hidden
* Note: To hide the root tag and show a child tag, use CSS styles `visibility: hidden` and `visibility: visible`, though the parent markup will still take up screen real estate

<<ext "StackOverflow Hide Parent Show Child tag">>

HTML CSS\HTTP-EQUIV Document Type

!! Simulate an HTTP Respsonse header

* The http-equiv attribute value `content-type` provides an HTTP header specifying that the character encoding for the document is in the content attribute

<<ext "W3Schools Meta HTTP-EQUIV">>

!! Sample code

```
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
```

HTML CSS\iFrame to Local HTML file

```
<iframe src="UrPath\UrFile.html" scrolling=yes style="border-style:none;height:75%;width:100%" ></iframe>

HTML CSS\Language attribute on tags

!! Allow screen-reader to identify the page's default language and / or accent

* tag name = any
* `lang` attr = an ISO-639 Language code
* The official W3C recommendation is to declare the primary language for each Web page with a &lt;...lang => attribute in the &lt;html> tag
* Note: The LANG tag (i.e. the lang="" attribute) is designed to signal screen readers pronunciation engines to switch to another language or accent

<<ext "PSU.edu LangTag">>

!! Sample code

```
<html lang="en-GB">
```

HTML CSS\META Tag names

!! Identify tool or program used to create the website

* tag name = `META`
* `name` attr = `generator`
* `content` attr = The name of the program you used to create your website
* Note: This tag is automatically inserted by website-generating applications
* Note :People who don’t want to advertise which tool or program they used to create the website can remove this tag from the generated pages

<<ext "MetaTags.org Generator">>

!! Sample code

```
<meta name="generator" content="UrProgramTitle" />
```

!! Identifies the name of the application running in the web page

* tag name = `META`
* name attr = `application-name`
* `content` attr = The application that is dynamically supplying content for the current web page
* Note: isolated web pages shouldn't define an application-name

<<ext "Mozilla.org META tags">>

```
<meta name="application-name" content="UrApplicationTitle" />
```

!! Supply hints about the size of the initial size of the viewport

* tag name = `META`
* `name` attr = viewport'
* `content` attr = comma-separated list of equates
* Note: This is used by mobile devices only
* Note: The default values may vary between devices and browsers
* Note: Disabling zooming capabilities by setting user-scalable to a value of no prevents people experiencing low vision conditions from being able to read and understand page content

<<<
* width = ( A positive integer number ) or ( the text `device-width` )
* height = ( A positive integer) or ( the text `device-height` )
* initial-scale = A positive number between 0.0 and 10.0
* maximum-scale = A positive number between 0.0 and 10.0
* minimum-scale = A positive number between 0.0 and 10.0
* user-scalable = `yes`, `no`
* viewport-fit = `auto', 'contain`, `cover`
<<<

<<ext "Mozilla.org META tags">>

!! Sample code

```
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
```

!! Include developer or company information in document

* tag name = `meta`
* `name` attr = `copyright`, `ur_app_name-version`
* `content` attr = Any text data
* Note: This information is not used by the browser

HTML CSS\Meta Tag Schema

<<ext "W3.org HTML401 Meta">>

This specification does not define a set of legal meta data properties.
The meaning of a property and the set of legal values for that property should be defined in a reference lexicon called a profile.

<<ext "W3.org HTML401 Profiles">>

The profile attribute of the HEAD specifies the location of a meta data profile.
The value of the profile attribute is a URI.
User agents may use this URI in two ways:

* As a globally unique name.

<<<
User agents may be able to recognize the name (without actually retrieving the profile) and perform some activity based on known conventions for that profile.
For instance, search engines could provide an interface for searching through catalogs of HTML documents, where these documents all use the same profile for representing catalog entries.
<<<

* As a link.

<<<
User agents may dereference the URI and perform some activity based on the actual definitions within the profile (e.g., authorize the usage of the profile within the current HTML document).
This specification does not define formats for profiles.
<<<


HTML CSS\Noscript alternate content

!! Add content when viewed with JavaScript-disabled browsers

* tag name = `noscript`
* Note: The tag contents are displayed to users that have disabled scripts in their browser or have a browser that doesn't support user action event scripting

<<ext "W3Schools NoScript tag">>

!! Sample code

```
</noscript>
<!--Javascript-disabled browser additional content-->
</noscript>
<!--Ordinary content-->
```

HTML CSS\Padding and Margin

```
style="margin-left:30px"

style="padding-left:10px"

HTML CSS\Table Rows Alternate

Stylesheet classes:

```
.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}
```

HTML using class

```
<table class="alternating-rows">
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

HTML CSS\Website icon

!! Show an icon next to the Website Name

* tag name = `link`
* `rel` attr = `icon`, `shortcut icon`
* `href` attr = Website icon filename, relative path, or full path
* Note: The favicon is loaded as soon as the browsers parses the link rel="icon" declaration, or after the page is loaded when the link is not found
* Note: The icon keyword may be preceded by the keyword "shortcut". If the "shortcut" keyword is present, the rel attribute's entire value must be an ASCII case-insensitive match for the string "shortcut icon" (with a single U+0020 SPACE character between the tokens and no other ASCII whitespace).

<<ext "MathiasBynens Rel Icon">>

<<ext "WHATWg.org Link Icon">>

!! Sample code

```
<link rel="shortcut icon" href="favicon.ico">
```

Instapaper

<<glbl_article_list>>

Instapaper\Export as CSV

"""
[https://www.instapaper.com/u]
- [Top-right icon]
- Click login-name menu, option Settings -> Navigates page
- [Settings page, Export section]
- Click link Download .CSV file -> Opens dialog
- Click button OK -> Starts download, closes dialog

[CSV file]
- Header fields =
"""

```
URL
Title
Selection
Folder
Timestamp
```

- Header line =

```
URL,Title,Selection,Folder,Timestamp
```

- Sample data 1 =

```
https://m.youtube.com/watch?v=ABC123DEF&index=14,"""UrQuotedText"" - UrVideoTitle",UrCommentText,"UrInstapaperFolder",1605840648
```

- Sample data 1 =

```
https://www.urcompany.com/urfolder/urarticle/,UrArticleTitle,,UrInstapaperFolder,UrCommentText1603883475
```

Instapaper\Parse file

```
\define link_title()
''[<$list filter="[<http_text>split[,]butlast[]last[]]" />]'' <$list filter="[<http_text>split[,]rest[]first[]]" />
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]floor[]]"><$vars tid_year=<<currentTiddler>> >
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]subtract<tid_year>multiply[12]floor[]]"><$vars tid_month=<<currentTiddler>> >
(<<tid_year>>-<<tid_month>>)
</$vars></$list>
</$vars></$list>
<ul>
<$list filter='[<http_text>split[,]butlast[]butlast[]butfirst[]butfirst[]join[,]split["]butfirst[]butlast[]join["]split[""]join["]split[...]]'>
<li><<currentTiddler>></li>
</$list>
</ul>
\end
<$list filter="[{WebNotes\Data}split[http]count[]]" ><$vars total_count=<<currentTiddler>> >Count of entries: <<total_count>><br><br>
<!--
<$button>
<$action-setfield $tiddler="$:/state/popup/audit_1k" text="0"/>
Reset
</$button><br>

<$button>
<$list filter="[{$:/state/popup/audit_1k}add[1000]]">
<$action-setfield $tiddler="$:/state/popup/audit_1k" text=<<currentTiddler>> />
Next 1k
</$list>
</$button><br>
{{$:/state/popup/audit_1k}}

<$list filter="[{WebNotes\Data}split[http]first{$:/state/popup/audit_1k}last[1000]]"><$vars http_text=<<currentTiddler>> >
-->
<$list filter="[{WebNotes\Data}split[{{]join[-opencurlybrace-]split[http]]"><$vars http_text=<<currentTiddler>> >
<$list filter="[<http_text>split[,]first[]!suffix[URL]addprefix[http]]"><$vars http_link=<<currentTiddler>> >
<$list filter="[all[tiddlers]field:twnote<currentTiddler>count[]match[0]]">
<<http_link>><br>
- <<link_title>> <br>
</$list>
</$vars></$list>
</$vars></$list>
</$vars></$list>
```

IrfanView

<<glbl_article_list>>

IrfanView\Contact Sheet

"""
[IrfanView app]
- Open one thumbnail image -> Loads image
- Click the File menu option Thumbnails -> Opens dialog
- [Thumbnails dialog]
- Select all files in the folder
- Click the File menu, option Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

JavaScript

<<glbl_article_list>>

JavaScript\Comment text

!! Place a comment text block inside of a JavaScript program

* tag name = `script`
* `type` attr = `text/javascript`
* Start JavaScript comment text block with forward-slash asterisk ( `/*` )
* End comment text with asterisk forward-slash ( `*/` )
* Start JavaScript comment text line with two forward-slashes ( `//` )

!! Sample code

```
<style type="text/javascript">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>
```

JavaScript\Execute Nameless Function

```
;(
    function() {
        alert('hi');
        }
    )();

JavaScript\Exports object

!! Determine if running under Node.JS

* Initially at least, `exports` is a reference to `module.exports`
* If you assign anything to `module.exports`, `exports` is not no longer a reference to it, and exports loses all its power

<<ext "SitePoint Exports Node.JS">>

JavaScript\Invalid Variable Names

<<ext "JavaScript Strict Mode">>

Strict mode makes assignments which would otherwise silently fail to throw an exception.  For example, NaN is a non-writable global variable. In normal code assigning to NaN does nothing; the developer receives no failure feedback. In strict mode assigning to NaN throws an exception.

```
'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError
```

Strict mode in ECMAScript 2015 forbids setting properties on primitive values. Without strict mode, setting properties is simply ignored (no-op), with strict mode, however, a TypeError is thrown.

```
(function() {
'use strict';

false.true = '';         // TypeError
(14).sailing = 'home';   // TypeError
'with'.you = 'far away'; // TypeError

})();
```

JavaScript\Labels

The labeled statement can be used with break or continue statements.

```
List: 
while(counter < 50)
{
     userInput += userInput;
     counter++;
     if(userInput > 10000)
     {
          break List;
     }
}
```

```
var i = 100, j = 100;
outerloop:
while(i>0) {
  while(j>0) {
   j++

   if(j>50) {
     break outerloop;
   }
  }
i++

}
```

```
loop1:
for (let i = 0; i < 5; i++) {
  if (i === 1) {
    continue loop1;
  }
  str = str + i;
}
```

JavaScript\Logical And/Or

If a value can be converted to true, the value is so-called truthy. If a value can be converted to false, the value is so-called falsy.

Examples of expressions that can be converted to false are:

* null
* NaN
* 0
* empty string ( ` "" ` or ` '' ` ) or empty template literal ( &#x0060;&#x0060; )
* undefined

The logical OR expression is evaluated left to right, and first truthy returned expression stops evaluation of the remaining expressions

The && operator is executed before the || operator

Note: If you use this operator to provide a default value to some variable, be aware that any falsy value will not be used. If you only need to filter out null or undefined, consider using the nullish coalescing operator ( ` ?? ` )

JavaScript\Multi-line string

It's not a multiline string, it's a one line string split over multiple lines of code that make up a single statement.

Old version uses backslash as a line continuation character:

```
eval(" \
alert('hi'); \
");
```

New version uses backtick character as multi-line string:

WARNING: Not supported by IE

```
eval(`
alert('hi');
`);
```

Use string concatenation instead:

```
eval(
"var v1 = 'hi';" +
"alert(v1);"
);
```


JavaScript\Run in HTML Document

```
<html>
  <body><script type = "text/javascript">window.onerror=function(msg,url,line){alert("Line number = "+line+"\nMessage:\n\n"+msg)}</script>
    <script type="text/javascript">
alert('hi';
      </script>
    </body>
  </html>

JavaScript\Strict Mode

!! Show strict mode compilation errors on specific scripts or functions

* First statement in script or function: 'use strict'; or "use strict";
* Note: Strict mode applies to entire scripts or to individual functions, not individual block statements enclosed in {} braces within a function
* Note: Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally
* Note: The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it

<<ext "MozillaDeveloper Strict mode">>

!! Sample data

```
"use strict";
mistypeVariable = 17;
```

<<<
Result in Developer Tools, Javascript Console:

```
Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLineNumber
```
<<<

```
<script type="module">
mistypeVariable = 17;
</script>
```

<<<
Result:

```
Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLine
```
<<<

JavaScript\String Escape Codes

"""
Here are all the string escape codes:

\0 The NUL character (\u0000)
\b Backspace (\u0008)
\t Horizontal tab (\u0009)
\n Newline (\u000A)
\v Vertical tab (\u000B)
\f Form feed (\u000C)
\r Carriage return (\u000D)
\" Double quote (\u0022)
\' Apostrophe or single quote (\u0027)
\\ Backslash (\u005C)
\x XX The Latin-1 character specified by the two hexadecimal digits XX
\u XXXX The Unicode character specified by the four hexadecimal digits XXXX

JavaScript\This object

<<ext "JavaScript This Parameter">>

Functions called via property references get "this" set for them: This is the part that really makes it seem like JavaScript has methods: The "this" reference gets set automagically to the object instance if you call a function via a property reference.

Within that call, use the object in question as "this". Getting the function reference from an object property doesn't link it in any way to the object the property came from. The JavaScript engine treats calls of functions just retrieved from object properties as special and sets up "this" accordingly. Essentially, "this" is just a function argument that's passed into the function as an implicit feature of calling a function via a property reference.

JavaScript gives us the call and apply methods on function instances, with which we can say explicitly what we want "this" to be. If you say myfunction.call(myobject), you're saying "call myfunction and use myobject as 'this'", which is what the property-retrieval stuff does implicitly for you.

`UrObject.UrFunction();`

- equates to -

`UrObject.UrFunction.call(UrObject);`

Everything can be seen as a function.

`window['UrObject']['UrFunction'].call(window['UrObject']);`

Getting the function reference from the property (UrObject.UrFunction) is distinct from the fact we're calling it (call) is distinct from what "this" should be ((UrObject)).

<<ext "JavaScript Closures">>

The interpreter creates a call object for this particular execution of the function and sets some properties on that call object before passing it into the function's code.

* A property called arguments which is an array (of sorts, in most implementations it's not actually an Array object) of the actual arguments we called the function with, plus a callee property which is a reference to the function being called.
* A property for each of the arguments defined by the function declaration. The values of these properties are set to the values passed into the function. If any arguments weren't specified (because JavaScript lets you call functions with however many arguments you want, regardless of the definition), properties for any missing arguments are still created on the call object — with the value undefined.
* A property for every declared variable within the function (e.g., every "var" statement). (These start out with the value undefined.)

```
window.UrFunction(UrObject1, UrObject2);
```

That creates a call object for this execution of updateDisplay that essentially looks like this:

```
call.arguments = [UrObject1, UrObject2]
call.arguments.callee = UrFunction
call.ur_input_parm1 = UrObject1
call.ur_input_parm2 = UrObject2
call.internal_var1 = undefined
```

The use of the call object is implicit, because once the call object is created, it's put at the top of the scope chain for the duration of the function call.

JavaScript\TypeOf Name

!! Get string representing object type

* typeof always returns a string
* Note: typeof operator takes precedence over string concatenation ( ` + ` )
* Note: type a let or const variable in a block before they are declared will throw a ReferenceError

* Undefined, undeclared variable, or unassigned variable = "undefined"
* Boolean(1), !!(1) = "boolean"
* Number('321') , Infinity, NaN = "number"
* Bigint, 321n = "bigint"
* String = "string"
* Symbol = "symbol"
* Function() {}, class UrClassName {},  = "function"
* null, object, {ur_prop_name: ur_prop_value}, [ur_val1, ur_val2, ur_val3], new Date(), /regex/ = "object"

JavaScriptBookmarklets

<<glbl_article_list>>

JavaScriptBookmarklets\Bibliographic citation

<<ext "ALAorg Citations bookmarklet">>
```
javascript:(function(){var h=document.createElement('div');var t=document.getElementsByTagName('title')[0];var info='<p><strong>Title('+t.innerHTML.length+'):</strong> '+t.innerHTML+'</p>';var m=document.getElementsByTagName('meta');for(var i=0;i < m.length;i++){if(null !==m[i].getAttribute('name')){var c=m[i].getAttribute('content');info+='<p><strong>'+m[i].getAttribute('name')+'('+c.length+'):</strong> '+c+'</p>';}}var lm=document.lastModified;var url=location.href;var d=new Date();var dd=d.getDate();var mm=d.getMonth()+1;var yyyy=d.getFullYear();info+='<p><strong>Citation: </strong>"' + t.innerHTML + '." Last modified '+lm+'. <a target="_blank" href="'+url+'">'+url+'</a> (accessed '+mm+'/'+dd+'/'+yyyy+').</p>';document.body.insertBefore(h,document.body.firstChild);h.innerHTML='<div style="border:1px solid %23888;border-radius:5px;-moz-box-shadow:0 0 5px %23888;-webkit-box-shadow:0 0 5px%23888;box-shadow:0 0 5px %23888;background:%23eee;text-align:left;padding:1em;"><a href="%23" onclick="document.body.removeChild(document.body.firstChild);return false">remove</a>'+info+'</div>';})();

JavaScriptBookmarklets\Clear all CSS

Clears all the CSS Class and Style attributes

```
avascript:(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["module"], factory);
  } else if (typeof exports !== "undefined") {
    factory(module);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod);
    global.clearAllCSS = mod.exports;
  }
})(this, function (module) {
  "use strict";

  var each = Array.prototype.forEach;


  function clearAllCSS(nest_level, cur_elt) {
    var _context2;
    if (!cur_elt) {
        throw new Error("No element specified.");
        }

    var _context;
    (_context = cur_elt.children, each).call(_context, function (child) {
        clearAllCSS(nest_level+1, child);
        });

    while(cur_elt.attributes.length > 0) {
        cur_elt.removeAttribute(cur_elt.attributes[0].name);
        }
    }

  module.exports = clearAllCSS;
});
document.querySelectorAll('iframe,script,noscript').forEach(function(element){if (element!=null){element.parentNode.removeChild(element)}});
clearAllCSS(1, document.body);
if (document.head!=null){document.head.parentNode.removeChild(document.head)};
document.querySelectorAll('link').forEach(function(element){if (element!=null){element.parentNode.removeChild(element)}});
document.body.style.fontSize=prompt("Please enter font multiplier", "2") + "00%";
undefined;

JavaScriptBookmarklets\Convert to Inline CSS

Run this script (it takes a while) and then save the web page. All the CSS properties are specified on each element, so it does not need to load any stylesheets.

<<ext "GitHub LukeHorvat Computed Style to Inline">>

```
avascript:(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["module"], factory);
  } else if (typeof exports !== "undefined") {
    factory(module);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod);
    global.computedStyleToInlineStyle = mod.exports;
  }
})(this, function (module) {
  "use strict";

  var each = Array.prototype.forEach;


  function computedStyleToInlineStyle(nest_level, parent_style, cur_elt) {
    var _context2;
    if (!cur_elt) {
        throw new Error("No element specified.");
        }

    var cur_style = getComputedStyle(cur_elt);
    var _context;
    (_context = cur_elt.children, each).call(_context, function (child) {
        computedStyleToInlineStyle(nest_level+1, cur_style, child);
        });

    var parent_copy = document.createElement("an_unknown_tag");
    if (nest_level > 1) {
        for (var pctr = 0; pctr < parent_style.length; pctr++) {
            var pname = parent_style[pctr];
            var pval = parent_style.getPropertyValue(pname);
            parent_copy.style[pname] = pval;
            }
        }

    var blank_element = document.createElement("an_unknown_tag");
    parent_copy.appendChild(blank_element);
    document.head.appendChild(parent_copy);
    var blank_style = getComputedStyle(blank_element);

    for (var dctr = 0; dctr < blank_style.length; dctr++) {
        if (dctr < cur_style.length) {
            var dname = blank_style[dctr];
            var dval = blank_style.getPropertyValue(dname);
			var cval = cur_style.getPropertyValue(dname);
            if (cval != dval && cur_elt.style[dname] != dval) {
                cur_elt.style[dname] = cval;
                }
            }
        }
    }

  module.exports = computedStyleToInlineStyle;
});
(function(){
	var h = document.createElement('div');
	var t = document.getElementsByTagName('title')[0];
	var cite_remove = '<a href="%23" onclick="document.body.firstChild.style.visibility = \'hidden\';document.body.firstChild.style.height = \'0px\';return false">remove</a>';
	var info = '<p><strong>Title(' + t.innerHTML.length + '):</strong> ' + t.innerHTML + '</p>';
	var m = document.getElementsByTagName('meta');
	for(var i = 0; i < ((m == null) ? 0 : m.length); i++) {
		if(null !== m[i].getAttribute('name') ) {
			var c=m[i].getAttribute('content');
			if (c != null) {info += '<p><strong>' + m[i].getAttribute('name') + '(' + c.length + '):</strong> ' + c + '</p>';}
			}
		}
	
	var lm = document.lastModified;
	var url = location.href;
	var d = new Date();
	var dd = d.getDate();
	var mm = d.getMonth()+1;
	var yyyy = d.getFullYear();
	info += '<p><strong>Citation: </strong>"' + t.innerHTML + '." Last modified ' + lm + '. <a target="_blank" href="' + url + '">' + url + '</a> (accessed ' + mm + '/' + dd + '/' + yyyy + ').</p><p><strong>Filename:</strong> ' + '0'.repeat(4-yyyy.toString().length) + yyyy + 'm'+'0'.repeat(2-mm.toString().length) + mm + 'd' + '0'.repeat(2-dd.toString().length) + dd + ' ' + url.replace('http://','').replace('https://','').replace('file:///','').replaceAll('/','-fslash-') + '.html</p>';
	document.body.insertBefore(h,document.body.firstChild);
	h.innerHTML='<div style="border:1px solid %23888;border-radius:5px;-moz-box-shadow:0 0 5px %23888;-webkit-box-shadow:0 0 5px%23888;box-shadow:0 0 5px %23888;background:%23eee;text-align:left;padding:1em;">' + cite_remove + info + cite_remove + '</div>';
	})();
document.querySelectorAll('iframe,script,noscript').forEach(function(element){element.parentNode.removeChild(element)});
computedStyleToInlineStyle(1, null, document.body);
document.head.parentNode.removeChild(document.head);
document.querySelectorAll('link').forEach(function(element){element.parentNode.removeChild(element)});
alert("done");

JavaScriptBookmarklets\Edit current page

Edit webpage

```
javascript:document.body.contentEditable = 'true'; document.designMode='on'; void 0
```

Editing Done

```
javascript:document.body.contentEditable = 'false'; document.designMode='off'; void 0
```

JavaScriptBookmarklets\Extract iFrame pages

```
(function(){ var imgs = document.getElementsByTagName('iframe'),t=[]; for (var i=0, n=imgs.length;i'+ imgs[i].src+''); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract images

```
avascript:(function(){ var imgs = document.getElementsByTagName('img'),t=[]; for (var i=0, n=imgs.length;i<n;i++) t.push('<a href="'+imgs[i].src+'"><img src="'+ imgs[i].src+'" width="100"></a>'); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract plain text

Copy the HTML body to a new window, so CSS and Javascript are ignored

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML;void(newWindow.focus());}
```

Copy the HTML body to a new window showing the HTML tags, so you can see the HTML code

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/&/g,"&amp;").replace(/</g,"<br>&lt;");void(newWindow.focus());}
```

Copy the HTML body without any HTML tags, so the text is loaded without any HTML or CSS styling

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/<[^>]+>/g, '<br>');void(newWindow.focus());}
```

JavaScriptBookmarklets\Unescape HTML code

```
avascript:document.documentElement.innerHTML='<html><body>'+document.body.innerHTML.replaceAll('&lt;','<').replaceAll('&gt;','>').replaceAll('&amp;','&')+'<\/body><\/html>';

JavaScriptBookmarklets\View HTML Source

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){;newWindow.document.documentElement.innerHTML='<html><head><title>Source of Page<\/title><\/head><body><pre>'+document.documentElement.outerHTML.replaceAll('&','&amp;').replaceAll('<','&lt;')+'<\/pre><\/body><\/html>';newWindow.document.body.contentEditable = 'true'; newWindow.document.designMode='on';void(newWindow.focus());}

JavaScriptBookmarklets\View HTML to TW

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){;newWindow.document.documentElement.innerHTML='<html><head><title>Source of Page<\/title><\/head><body><pre>'+document.documentElement.outerHTML.replaceAll('&','&amp;').replaceAll('<','&lt;').replaceAll('&lt;html','&lt;div').replaceAll('&lt;\/html','&lt;\/div').replaceAll('&lt;body','&lt;div').replaceAll('&lt;\/body','&lt;\/div').replaceAll('position: absolute','position: relative').replaceAll('position: fixed','position: relative').replaceAll('position: flex','position: relative').replaceAll('>remove&lt;\/a>','&gt;&lt\/a&gt;').replaceAll('src="http','src_attr="http').replaceAll('src=\'http','src_attr=\'http')+'<\/pre><\/body><\/html>';newWindow.document.body.contentEditable = 'true'; newWindow.document.designMode='on';void(newWindow.focus());}

keyboard action FontLarge

<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/fontsize" text="24px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/lineheight" text="30px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize" text="25px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodylineheight" text="34px"/>

keyboard action FontNormal

<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/fontsize" text="14px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/lineheight" text="20px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize" text="15px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodylineheight" text="24px"/>

keyboard action HomeTiddlers

<$action-sendmessage $message="tm-home"/>

keyboard action Preview

<$list filter="[[$:/state/showeditpreview]get[text]!match[yes]]"><$action-setfield $tiddler="$:/state/showeditpreview" text="yes"/></$list>
<$list filter="[[$:/state/showeditpreview]get[text]match[yes]]"><$action-setfield $tiddler="$:/state/showeditpreview" text="no"/></$list>


keyboard action SaveAllChanges

\define ExportSaveAll(ur_filename, ur_stamp, ur_save_wiki_extension, ur_save_export_html)
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" filename="WikiMove_$ur_filename$-stamp-$ur_stamp$$ur_save_wiki_extension$"
/>
<$list variable=save_export_html filter="[[$ur_save_export_html$]match[1]]">
<$list variable=save_as_html_path filter="[[$ur_filename$]split[-fslash-src-fslash-]join[-fslash-]addprefix[WikiMove_]addsuffix[-stamp-$ur_stamp$.html]]">
<$action-sendmessage $message="tm-download-file"
$param="$:/core/templates/exporters/StaticRiver" filename=<<save_as_html_path>>
exportFilter="""[all[tiddlers]tag[INDEX]sort[title]][all[tiddlers]!tag[EXT]!tag[INDEX]!tag[META]!tag[MCR]!prefix[Draft of]!is[image]!is[tag]!is[system]sort[title]]"""/>
</$list><!--save_as_html_path-->
</$list><!--save_export_html-->
<$action-sendmessage $message="tm-download-file"
$param="template ExportAllCode" filename="WikiMove_$ur_filename$-stamp-$ur_stamp$.card.txt" />
\end
<$list variable=save_export_html filter="[{$:/info/url/full}suffix[.htm]count[]] [[parm SkipSaveExportHTML]is[tiddler]count[]multiply[-1]] +[sum[]]">
<$list variable=save_wiki_extension filter="[{$:/info/url/full}split[.]last[]addprefix[.]]">
<$list variable=save_as_file_name filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.html]join[]split[.htm]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<save_as_file_name>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> ur_save_wiki_extension=<<save_wiki_extension>> ur_save_export_html=<<save_export_html>> />
</$list><!--save_as_file_name-->
</$list><!--save_wiki_extension-->
</$list><!--save_export_html-->

mcr glbl_article_list

\define glbl_article_list()
<ol>
<$list variable=card_prefix filter="[<currentTiddler>addsuffix[\]]">
<$list variable=cur_card filter="[prefix<card_prefix>sort[]]">
<$list variable=disp_name filter="[<cur_card>split[\]butfirst[]join[\]]">
<li><$link to=<<cur_card>> ><<disp_name>></$link></li>
</$list><!--disp_name-->
</$list><!--cur_card-->
</$list><!--card_prefix-->
</ol>
\end
\define glbl_article_checklist()
<$vars cur_card=<<currentTiddler>> >
<<glbl_dt_ddd>>
<$wikify name=cur_date text="""<<now "YYYYm0MMd0DD">>""" >
<$list variable=diff_date filter="[<cur_card>get[match_date]else[]!match<cur_date>]">
<$button>
<$list variable=field_name filter="[<cur_card>fields[]prefix[chk_]]">
<$action-setfield $field=<<field_name>> $value="" />
</$list><!--field_name-->
<$action-setfield match_date=<<cur_date>> />
Clear all checkmarks
</$button>
</$list><!--diff_date-->
</$wikify><!--cur_date-->
<ol>
<$list variable=card_prefix filter="[<cur_card>addsuffix[\]]">
<$list variable=cur_entry filter="[prefix<card_prefix>sort[]]">
<$list variable=disp_name filter="[<cur_entry>split[\]last[]]">
<$list variable=chk_name filter="[<disp_name>addprefix[chk_]split[ ]join[_]lowercase[]]">
<li>
<$checkbox default="no" unchecked="no" checked="yes" tiddler=<<cur_card>> field=<<chk_name>> >
<$link to=<<cur_entry>> ><<disp_name>></$link>
</$checkbox>
</li>
</$list><!--chk_name-->
</$list><!--disp_name-->
</$list><!--cur_card-->
</$list><!--card_prefix-->
</ol>
</$vars>
\end

mcr glbl_code_split

\define glbl_code_block(ur_note_pk)
[[$ur_note_pk$]]
<$codeblock code={{$ur_note_pk$}} />
\end
\define glbl_code_linenum(ur_note_pk, ur_skip_count, ur_section_size, ur_disp_linenum)
<div style="clear:both">[[$ur_note_pk$]]</div>
<$list filter="[[$ur_skip_count$]!match[]else[0]]" variable=intSKIP_COUNT>
<$list filter="[[$ur_note_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>count[]]" variable=intLINE_COUNT>
<$list filter="[[$ur_section_size$]!match[]!match[0]else<intLINE_COUNT>]" variable=intSECTION_SIZE>
<$list filter="[range<intSECTION_SIZE>]" variable=intCUR_LINE>
<$list filter="[<intCUR_LINE>subtract[1]]" variable=IntREMOVE_LINE>
<$list filter="[[$ur_note_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>butfirst<IntREMOVE_LINE>first[]]" variable=strCUR_LINE>
<$list filter="[[$ur_disp_linenum$]!match[n]!match[0]]"><div style="float:left"><<intCUR_LINE>></div></$list>
<$codeblock code=<<strCUR_LINE>> />
</$list></$list></$list></$list></$list></$list>
\end
\define glbl_code_split_group(ur_note_pk, ur_skip_count)
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]splitregexp[\u0009]join[__	__]splitregexp[\u0020]join[__ __]splitregexp[\u0022\u0022\u0022]join[&#x0022;&#x0022;&#x0022;]]"><<currentTiddler>>
</$list></$list>
\end
\define glbl_code_split_count(ur_note_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_split_group ur_note_pk="$ur_note_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_split_data()
<$macrocall $name=glbl_code_split_count ur_note_pk=<<source_note_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_split_next_group_disp(ur_rem_counter)
<$list filter="[{$ur_rem_counter$}subtract[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_split_disp(ur_source_note_pk, ur_temp_note_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_note_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to find: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
Source data: [[$ur_source_note_pk$]]<br>
\end
\define glbl_code_split_combine()
$(currentTiddler)$$(str_html_out)$
\end
\define glbl_code_split_init(ur_note_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_note_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]add[1]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_note_pk>> text="" />
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_split(ur_note_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_split_init ur_note_pk="$ur_note_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_note_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_split_disp ur_source_note_pk=<<source_note_pk>> ur_temp_note_pk=<<temp_note_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$wikify name=str_html_out text=<<glbl_code_split_data>> >
        <$list filter="[<temp_note_pk>get[text]else[]]"><$vars combine_html_out=<<glbl_code_split_combine>> >
        <$action-setfield $tiddler=<<temp_note_pk>> text=<<combine_html_out>> />
         </$vars></$list>
        <$macrocall $name=glbl_code_split_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> />
        </$wikify>
      
      Find next 100 lines
      </$button><br>

    <$edit-text tiddler=<<temp_note_pk>> autoHeight=no />
    </$vars>
  </$list>
\end
\define glbl_code_disp_group(ur_note_pk, ur_skip_count)
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u00A0]join[&nbsp;]splitregexp[\u0009]join[&nbsp;&nbsp;&nbsp;&nbsp;]splitregexp[\u0020]join[&nbsp;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]]"><<currentTiddler>><br></$list></$list>
\end
\define glbl_code_disp_count(ur_note_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_note_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_disp_data()
<$macrocall $name=glbl_code_disp_count ur_note_pk=<<source_note_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_disp_next_group_disp(ur_rem_counter, ur_oper)
<$list filter="[{$ur_rem_counter$}$ur_oper$[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_disp_disp(ur_source_note_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_note_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to browse: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
\end
\define glbl_code_disp_init(ur_note_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_disp(ur_note_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_disp_init ur_note_pk="$ur_note_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
[[$ur_note_pk$]]<br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_disp_disp ur_source_note_pk=<<source_note_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="subtract" />
      
      Browse next 100 lines
      </$button><br>
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="add" />
      
      Browse prev 100 lines
      </$button><br>

    <<glbl_code_disp_data>>
    </$vars>
  </$list>
\end

<!--<$macrocall $name=glbl_code_disp ur_note_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_disp "WebNotes\Data 1 >>-->

<!--Does not pass through the \u0009 tab or \u00A0 non-breaking space characters. Chrome highlight and copy puts spaces on the clipboard.-->

<!--[[WebNotes\Data]]-->

<!--<$macrocall $name=glbl_code_split ur_note_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_block "UrNotePK">>-->

<!--<<glbl_code_linenum "UrNotePK" 0 15 n>>-->

mcr glbl_compare_lines

\define glbl_compare_lines_results_table(ur_note_pk, ur_second_pk, ur_row_count)
<table><tr>
<th>''Line''</th>
<th>Show text</th>
<th>First Side<br>Second Side</th>
</tr>
<$list filter="[range<intSECOND_COUNT>subtract[1]]" variable="intCUR_ENTRY">
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]]" variable="strFIRST_LINE">
<$list filter="[{$ur_second_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]!match<strFIRST_LINE>]" variable="strSECOND_LINE">
<tr>
<td rowspan=2>

!!<<intCUR_ENTRY>>
</td>
<td>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/CompareTextSection1" text="""<$edit-text tiddler="$:/state/CompareTextLine1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/CompareTextLine1}!match[]else[0]]" variable=intSTART_LINE><$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_note_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_note_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/CompareTextSection1"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strFIRST_LINE>> /></td>
</tr>
<tr>
<td>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/CompareTextSection2" text="""<$edit-text tiddler="$:/state/CompareTextLine2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/CompareTextLine2}!match[]else[0]]" variable=intSTART_LINE>
<$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_second_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_second_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/CompareTextSection2"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strSECOND_LINE>> /></td>
</tr>
</$list></$list></$list>
</table>
\end
\define glbl_compare_lines(ur_note_pk, ur_second_pk)
<$list filter="[{$ur_note_pk$}splitregexp[\n]count[]]" variable="intFIRST_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]]" variable="intSECOND_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]subtract<intFIRST_COUNT>]" variable="intSECOND_EXTRA">

[[$ur_note_pk$]] line count: <<intFIRST_COUNT>>

[[$ur_second_pk$]] line count: <<intSECOND_COUNT>>

''$ur_second_pk$'' excess line count: ''<<intSECOND_EXTRA>>''

<$macrocall $name=glbl_compare_lines_results_table ur_note_pk="$ur_note_pk$" ur_second_pk="$ur_second_pk$" ur_row_count=<<intSECOND_COUNT>> />
</$list>
</$list>
</$list>
\end

<!--
<$edit-text tiddler="$:/state/CompareText1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>
<$edit-text tiddler="$:/state/CompareText2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>

<<glbl_compare_lines "$:/state/CompareText1" "$:/state/CompareText2">>
-->

mcr glbl_dt_ddd

\define glbl_dt_ddd()
<div style="clear:right;float:right;background-color:aquamarine;"><<now "YYYYm0MMd0DD DDD pm0hh12\m0mm">></div>
<$list filter="[<currentTiddler>split[Draft of ']join[]split[ ]first[]split[m]join[]split[d]join[]]">
<$view field="title" format="date" template="[UTC]DDD" />
</$list>
\end

mcr glbl_ext

\define ext(ur_extnote_pk)
<$list variable=missing_entry filter="[[ext $ur_extnote_pk$]get[text]else[]match[]]">Missing: [$ur_extnote_pk$]
</$list><!--missing_entry-->
<$list variable=prefix_dir filter="[{$:/info/url/full}split[/src/]count[]match[2]then[../]else[]]">
<$list variable=found_entry filter="[[ext $ur_extnote_pk$]get[text]else[]addprefix<prefix_dir>]">
<a target="_blank" href=<<found_entry>> >$ur_extnote_pk$</a><div style="float:right">[[->|ext $ur_extnote_pk$]]</div>
</$list><!--found_entry-->
</$list><!--prefix_dir-->
\end

MicrosoftRemoteDesktop

<<glbl_article_list>>

MicrosoftRemoteDesktop\Setup PC

<<ext "Microsoft RemoteDesktop Enable">>

Panel

* https://github.com/settings/tokens
>* If there is an existing personal access token,
>>* Click on the name -> Navigates page
>>* Click button Regenerate Token -> Navigates page
>>* Click button Copy to Clipboard
>* Otherwise create a new token
* https://github.com/settings/tokens/new
>* Note = name of end user and device
>>* Must be unique
>>* Each device should get a different token
>* checkbox "repo" = set
>* Click button Generate token -> Navigates page
>* Click button Copy to Clipboard
!!
* <$link to="$:/ControlPanel" />
>* [Saving tab, GitHub Saver sub-tab]
>* Paste into field "Password, OAUTH token, or personal access token"
>* Close the Control Panel card
!!
* Click button <$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" />
Save Wiki
</$button>
>* Wait a few seconds for the "Saved wiki" notification
>* The token is saved in internal browser storage
>* If you get a "401" error, go back to step 1 to generate a new token

Recent Entries

[[Search All Fields]]

[[Tags Count Audit]]

[[View All Cards]]

[[View All Code]]

[[Font Size]]

<<timeline limit:30 format:"YYYY-0MM-0DD">>

Regular Expressions

<<glbl_article_list>>

Regular Expressions\Explanation

\define disp_re(ur_list, ur_re)
<$vars re="$ur_re$">
`$ur_list$` matches `$ur_re$`?
<$list variable=ret filter="[[$ur_list$]regexp<re>else[no]]"> -,/<<ret>>\,- </$list>

`$ur_list$` split out `$ur_re$`?
<$list variable=ret filter="[[$ur_list$]splitregexp<re>]"> -,/<<ret>>\,- </$list></$vars>
<!--
disp_re-->
\end
[[TiddlyWiki\Regular Expression]]

<<ext "Regexp Filter with brackets">>

<<<
The code would get complexer ^^[sic]^^ too as "[''''[...]'''']" can't be put directly in the regex in TW. You'd have to do it through a variable. And since "[character class]" is reserved in regex you'd also have to escape square brackets "[\[\]]".
<<<

<<ext "Regular Expression Quantifiers">>

Regular expressions take a string of text, and returns a YES or NO as to whether it matches a character pattern.

You can specify a literal character.

* A letter or series of letters
** <<disp_re "ABC" "B">>
* `\`. is a literal period, because without the \ escape it would have special meaning
** <<disp_re "AA.AA" "\.">>

You can use tokens to specify a kind of character to match.

* `\d` is a numeric digit 0 through 9
** <<disp_re "A2C" "\d">>

* `\D` is any non-numeric digit
** <<disp_re "5A8" "\D">>

* `\s` is a whitespace character; like space, tab, or line feed
** <<disp_re "A C" "\s">>

* `\S` is a non-whitespace character
** <<disp_re "A" "\S">>

* `\W` is a whitespace or punctuation character (non-word character)
** <<disp_re ";" "\W">>

* `\w` is a word character (non-whitespace and non-punctuation character)
** <<disp_re "A" "\w">>

* `.` period is any character
** <<disp_re "A" ".">>

You can get out of having to use the \ escape over a block of text if you prefer to type it out.

* `\QOne. Two. Three.\E`  treats anything between the delimiters as a literal string, like "One. Two. Three."
** Useful to escape metacharacters
** Otherwise the periods would be special characters applied to the one letter before each period
** You can also write it as `One\. Two\. Three\.`

A regex quantifier such as `+` tells the regex engine to match a certain quantity of the character, token or subexpression immediately to its left.

* `A+` the quantifier + applies to A
** <<disp_re "AAABCCC" "B+">>
** <<disp_re "AAABBBCCC" "B+">>
* `A*` the quantifier * applies to A
** <<disp_re "ABBBC" "B*">>
** <<disp_re "AC" "B*">>
* `ABC?` the quantifier `?` applies to the C—not to ABC
** <<disp_re "ABCD" "BC?">>
** <<disp_re "ABD" "BC?">>
* `(?:A|B|C)+` the quantifier + applies to the subexpression
** <<disp_re "ABCD" "(?:B|C)+">>
** <<disp_re "ABD" "(?:B|C)+">>
* `\QA.B.C\E+` is treated as a sequence of literals, so the quantifier only applies to the last character
** This could also be written as `A\.B\.C+`

By default, a quantifier tells the engine to match as many instances of its quantified token or subpattern as possible. This behavior is called greedy.

* `A+` is greedy, and matches all the number characters in a row from the starting point where exists (a number)
** <<disp_re "ABBBCD" "B+">>
* `A+B` is greedy, and matches all the number characters in a row where exists (a letter B after a letter A)
** <<disp_re "ABBBCD" "B+C">>
** <<disp_re "ABBBCD" "(B+)C">>

In contrast to the standard greedy quantifier, which eats up as many instances of the quantified token as possible, a lazy (sometimes called reluctant) quantifier tells the engine to match as few of the quantified tokens as needed.

* `\w*?B` is lazy, and matches as few word characters in a row as needed where exists (a letter B after a word character)
** <<disp_re "+ABCCC+" "\w*?C">>
** <<disp_re "+ABCCC+" "\w*C">>

In contrast to the standard docile quantifier, which gives up characters if needed in order to allow the rest of the pattern to match, a possessive quantifier tells the engine that even if what follows in the pattern fails to match, it will hang on to its characters.

* A++ is possessive—it matches as many characters as needed and never gives any of them back.
** Whereas the regex A+. matches the string AAA, A++. doesn't. At first, the token A++ greedily matches all the A characters in the string. The engine then advances to the next token in the pattern. The dot . fails to match because there are no characters left to match. The engine looks if there is something to backtrack. But A++ is possessive, so it will not give up any characters. There is nothing to backtrack, and the pattern fails. In contrast, with A+., the A+ would have given up the final A, allowing the dot to match.

You can specify a number range of characters to repeat.

* A{2,9} uses two to nine As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
** <<disp_re "+ABCCC+" "C{1,2}">>
** <<disp_re "+ABCCC+" "C{2,2}">>
** <<disp_re "+ABCCC+" "C{2,9}">>
* A{2,} uses two or more As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
** <<disp_re "+ABCCC+" "C{2,}">>

You can use negated character classs to match characters other up to the one you want.

* `^[^\.]*` skips up to first period
** <<disp_re "AB.C.D" "^[^\.]*">>
* `^.*\.` skips up to last period
** <<disp_re "AB.C.D" "^.*\.">>

Tempered Greedy Token Solution

* `A(?:(?!B).)*B` stops at the first B instead of the last B
** <<disp_re "AB.C.DCE" "B(?:(?!C).)*C">>
** <<disp_re "AB.C.DCE" "B.*C">>

* `A(?:(?!C)(?!B).)*B` stops at the first B unless there is a C between the A and B
** <<disp_re "AB.CA" "B(?:(?!D)(?!C).)*C">>
** <<disp_re "AB.CAB.FGHBC" "B(?:(?!D)(?!C).)*C">>
** <<disp_re "AB.CAB.DFGHBC" "B(?:(?!D)(?!C).)*C">>

Search All Fields

<$vars search_text_pk="$:/state/popup/SearchAllFields">
<$list variable=show_code_pk filter="[<search_text_pk>addsuffix[-checkShowCode]]">
<$list variable=skip_system_pk filter="[<search_text_pk>addsuffix[-checkSkipSystem]]">
<$edit-text tiddler=<<search_text_pk>> field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler=<<skip_system_pk>>> Skip System </$checkbox><br>
<br>

<$list variable=cur_search_text filter="[<search_text_pk>get[text]addsuffix[(?i)]!match[]]">
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]else[no]]">
<$list variable=cur_skipsystem_text filter="[<skip_system_pk>get[text]else[yes]match[yes]count[]]">

<!--Card titles-->
<$list variable=cur_pk filter="[regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_skipsystem_text>] [<cur_pk>!is[system]count[]] +[sum[]match[1]]">

<$link to=<<cur_pk>> />: title
</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

<!--Card fields-->
<$list variable=cur_pk filter="[!regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_pk>is[system]count[]multiply<cur_skipsystem_text>match[0]]">
<$list variable=cur_field filter="[<cur_pk>fields[]]">
<$list variable=found_field filter="[<cur_pk>get<cur_field>regexp<cur_search_text>]">

<$link to=<<cur_pk>> />: <<cur_field>>
<$list variable=disp_code filter="[<cur_showcode_text>match[yes]]">
<$codeblock code=<<found_field>> />
</$list><!--disp_code-->
</$list><!--found_field-->
</$list><!--cur_field-->

</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

</$list><!--cur_skipsystem_text-->
</$list><!--cur_showcode_text-->
</$list><!--cur_search_text-->
</$list><!--skip_system_pk-->
</$list><!--show_code_pk-->
</$vars><!--search_text_pk-->

SQLite

<<glbl_article_list>>

SQLite\Blob text

<<ext "SQLite Blob text">>

```
WITH RECURSIVE test(c,cur) as (
     SELECT '', HEX(blob_field) FROM UrTable WHERE UrPK = 6
   UNION ALL
    select c || char((case substr(cur,1,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,1,1) end)*16
               + (case substr(cur,2,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,2,1) end)),
substr(cur,3)
from test where length(cur)>0
)
select * from test
```

SQLite\Database Browser

<<ext "SQLite DB Browser">>

I used `DB Browser for SQLite - .zip (no installer) for 64-bit Windows`

SQLite\Information Schema

<<ext "SQLite schema information">>

```
SELECT name, sql FROM sqlite_master
WHERE type='table'
ORDER BY name;
```

<<ext "SQLite Language functions">>

sqlite_source_id()

```
--version string of SQLite Library source code
2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f
```

sqlite_version()

```
--version string of SQLite Library running
3.33.0
```

SQLite\String Manipulation

<<ext "SQLite Language functions">>

```
--comment
```

CHAR(unicode_char_list)

COALESCE(field_list)

HEX(field)

IFNULL(field, default_text)

INSTR(field, search_text)

LENGTH(field)

LIKE(field, comparison_text)

* field LIKE comparisontext
* LIKE(field, comparison_text, escape_char)

LOWER(field)

LTRIM(field)

* LTRIM(field, chars_to_remove)

PRINTF(format_text, field_list)

REPLACE(field, search_text, new_text)

RTRIM(field)

* RTRIM(field, chars_to_remove)

SUBSTR(field, start_char)

* SUBSTR(field, start_char, char_count)

TRIM(field)

* TRIM(field, chars_to_remove)

typeof(field)

* "null", "integer", "real", "text", or "blob".

UNICODE(number)

UPPER(field)

SQLite\Top or Limit records

<<ext "SQLite Top 5 Records">>

SELECT * FROM Table_Name LIMIT 5;

Tags Count Audit

<$list variable=cur_card filter="[!has[tags]!prefix[$:]]">

<$link to=<<cur_card>> />
</$list><!--cur_card-->

---
<$list variable=cur_card filter="[!tag[DOC]!tag[EXT]!tag[IMG]!tag[INDEX]!tag[META]has[tags]!prefix[$:]]">
<$list variable=filter_tag_count filter="[<cur_card>tags[]butfirst[]first[]count[]match[0]]">

<$link to=<<cur_card>> />
</$list><!--filter_tag_count-->
</$list><!--cur_card-->

template ExportAllCode

\define renderContent()
<$list variable=cur_tip_pk filter="[all[tiddlers]!has[draft.of]!is[image]has[tags]!prefix[undefined]] [!prefix[$]!has[draft.of]!is[image]!has[tags]!prefix[undefined]] +[sort[title]]">
<hr>
<h2><$link to=<<cur_tip_pk>> /></h2>
<$list variable=cur_tip_text filter="[<cur_tip_pk>get[text]]">
<$codeblock code=<<cur_tip_text>> />
</$list><!--cur_tip_text-->
</$list><!--cur_tip_pk-->
\end
<<renderContent>>

template Home Button

<$list variable=on_twcard filter="[<tv-config-toolbar-icons>!match[no]]">
<div style="float:right;padding-left:30px;">
{{$:/core/ui/TopBar/menu}}
</div>

<div style="float:right"><$button set="$:/state/sidebar" setTo="no" tooltip={{$:/language/Buttons/Home/Hint}} aria-label={{$:/language/Buttons/Home/Caption}} class=<<tv-config-toolbar-class>>>
<span class="tc-dirty-indicator">
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/home-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Home/Caption}}/></span>
</$list>
</span>
<$action-sendmessage $message="tm-home"/>
</$button></div>
</$list><!--on_twcard-->

TiddlyWiki

<<glbl_article_list>>

TiddlyWiki\Add Tag to All Cards

```
<$button>
<$action-setfield $tiddler="Test1" tags="COPY"/>
Reset Test1 Card's Tag list with just COPY
</$button>

<$button>
<$list variable=cur_card filter="[is[tiddler]!prefix[$:/state/]]">
<$list variable=has_tag filter="[<cur_card>tags[]count[]!match[0]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[append[COPY]]"/>
</$list>
</$list>
Append COPY tag to all Cards that already have tags
</$button>

<$button>
<$list variable=cur_card filter="[tag[COPY]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[remove[COPY]]"/>
</$list>
Remove COPY tag from all Cards
</$button>

TiddlyWiki\Backlink to HTML,HTM

Title = ext TW Return

```
\define TW_Return(ur_url, ur_link_title)
<div style="float:right"><a href="$ur_url$"> ($ur_link_title$)</a></div>
\end
<$list filter="[<tv-config-toolbar-icons>match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="TiddlyWiki view of website" />
</$list>
</$list>
<$list filter="[<tv-config-toolbar-icons>!match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]split[.htm]join[.html]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="Static HTML view of website" />
</$list>
</$list>

TiddlyWiki\Button navigate to Card

```
<$vars new_code="Test1">
<$list variable=new_pk filter="[<new_code>addprefix[$:/state/popup/]]">
<$button>
<$action-sendmessage $message="tm-new-tiddler" title=<<new_pk>> tags="OneTag [[Another Tag]]" text=<<now "Today is DDth, MMM YYYY">>/>
Create Code ''<<new_code>>'' and Edit
</$button><br>

<$button>
<$action-setfield $tiddler=<<new_pk>> text="yes"/>
<$action-navigate $to=<<new_pk>>/>
Create Code ''<<new_code>>'' and Show
</$button><br>

<$link to=<<new_pk>> /><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
Close Code: ''<<new_code>>''
</$button><br>

<$list filter="[<currentTiddler>!prefix[Draft of]]" variable=strCARD_PK>
<$button>
<$list filter="[list[$:/StoryList]] -[<strCARD_PK>]" variable=strCLOSE_PK>
<$action-sendmessage $message="tm-close-tiddler" $param=<<strCLOSE_PK>>/>
</$list>
Close all other open Codes
</$button>
</$list><br>

<$button>
<$action-sendmessage $message="tm-delete-tiddler" $param=<<new_pk>> />
Delete Card: ''<<new_card>>'' with confirmation
</$button><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
<$action-deletetiddler $tiddler=<<new_pk>> />
Delete Card: ''<<new_card>>'' without confirmation
</$button>
</$list><!--new_pk-->
</$vars><!--new_card-->

TiddlyWiki\Button Set Field

```
<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="yes"/>
Set UrCardPK = yes
</$button>

<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="no"/>
Set UrCardPK = no
</$button>

TiddlyWiki\Checkbox edit

```
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler="$:/state/popup/checkUseIt">Use It</$checkbox>

TiddlyWiki\Clipboard Copy

Tags = `$:/tags/Macro`

```
\define cboard_copy(ur_text)
<pre>$ur_text$</pre>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end
\define cboard_pwd(ur_text ur_pk)
<$reveal type="nomatch" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="show">Show</$button>

</$reveal>
<$reveal type="match" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="hide">Hide</$button>
<pre>$ur_text$</pre>
</$reveal>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end

TiddlyWiki\Code View or Copy data

Title = `mcr glbl_code_split`

Tags = `$:/tags/Macro`

```
\define glbl_code_block(ur_card_pk)
[[$ur_card_pk$]]
<$codeblock code={{$ur_card_pk$}} />
\end
\define glbl_code_linenum(ur_card_pk, ur_skip_count, ur_section_size, ur_disp_linenum)
<div style="clear:both">[[$ur_card_pk$]]</div>
<$list filter="[[$ur_skip_count$]!match[]else[0]]" variable=intSKIP_COUNT>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>count[]]" variable=intLINE_COUNT>
<$list filter="[[$ur_section_size$]!match[]!match[0]else<intLINE_COUNT>]" variable=intSECTION_SIZE>
<$list filter="[range<intSECTION_SIZE>]" variable=intCUR_LINE>
<$list filter="[<intCUR_LINE>subtract[1]]" variable=IntREMOVE_LINE>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>butfirst<IntREMOVE_LINE>first[]]" variable=strCUR_LINE>
<$list filter="[[$ur_disp_linenum$]!match[n]!match[0]]"><div style="float:left"><<intCUR_LINE>></div></$list>
<$codeblock code=<<strCUR_LINE>> />
</$list></$list></$list></$list></$list></$list>
\end
\define glbl_code_split_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]splitregexp[\u0009]join[__	__]splitregexp[\u0020]join[__ __]splitregexp[\u0022\u0022\u0022]join[&#x0022;&#x0022;&#x0022;]]"><<currentTiddler>>
</$list></$list>
\end
\define glbl_code_split_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_split_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_split_data()
<$macrocall $name=glbl_code_split_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_split_next_group_disp(ur_rem_counter)
<$list filter="[{$ur_rem_counter$}subtract[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_split_disp(ur_source_card_pk, ur_temp_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to find: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
Source data: [[$ur_source_card_pk$]]<br>
\end
\define glbl_code_split_combine()
$(currentTiddler)$$(str_html_out)$
\end
\define glbl_code_split_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]add[1]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_card_pk>> text="" />
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_split(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_split_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_split_disp ur_source_card_pk=<<source_card_pk>> ur_temp_card_pk=<<temp_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$wikify name=str_html_out text=<<glbl_code_split_data>> >
        <$list filter="[<temp_card_pk>get[text]else[]]"><$vars combine_html_out=<<glbl_code_split_combine>> >
        <$action-setfield $tiddler=<<temp_card_pk>> text=<<combine_html_out>> />
         </$vars></$list>
        <$macrocall $name=glbl_code_split_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> />
        </$wikify>
      
      Find next 100 lines
      </$button><br>

    <$edit-text tiddler=<<temp_card_pk>> autoHeight=no />
    </$vars>
  </$list>
\end
\define glbl_code_disp_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u00A0]join[&nbsp;]splitregexp[\u0009]join[&nbsp;&nbsp;&nbsp;&nbsp;]splitregexp[\u0020]join[&nbsp;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]]"><<currentTiddler>><br></$list></$list>
\end
\define glbl_code_disp_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_disp_data()
<$macrocall $name=glbl_code_disp_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_disp_next_group_disp(ur_rem_counter, ur_oper)
<$list filter="[{$ur_rem_counter$}$ur_oper$[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_disp_disp(ur_source_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to browse: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
\end
\define glbl_code_disp_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_disp(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_disp_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
[[$ur_card_pk$]]<br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_disp_disp ur_source_card_pk=<<source_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="subtract" />
      
      Browse next 100 lines
      </$button><br>
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="add" />
      
      Browse prev 100 lines
      </$button><br>

    <<glbl_code_disp_data>>
    </$vars>
  </$list>
\end

<!--<$macrocall $name=glbl_code_disp ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_disp "WebNotes\Data 1 >>-->

<!--Does not pass through the \u0009 tab or \u00A0 non-breaking space characters. Chrome highlight and copy puts spaces on the clipboard.-->

<!--[[WebNotes\Data]]-->

<!--<$macrocall $name=glbl_code_split ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_block "UrCardPK">>-->

<!--<<glbl_code_linenum "UrCardPK" 0 15 n>>-->

TiddlyWiki\Codeblock Widget

\define sample_data_e1()
```
sample code "here" and "there"
```
\end

\define sample_data_e2()
<$codeblock code="""sample code "here" and "there"
"""/>
\end

\define sample_data_e3() \define sample_data_e3() sample code "here" and "there"

\define sample_data_e4()
\define sample_data_e4()
sample
code """here"""
and "there"
\end <--Last line of macro
\end

\define sample_data_e5()
<$codeblock code={{{ [[UrCardPK]get[text]] }}}/>
\end

<$codeblock code=<<sample_data_e1>>/>

You can use the `<$codeblock>` widget to display text as the three-backticks TiddlyWiki formatting block. Make sure to put an enter at the end of the string if it ends with d-quotes.

<$codeblock code=<<sample_data_e2>>/>

If you need to show text triple d-quotes in a code string, define a macro to return the string literal instead of passing in a code string.

<$codeblock code=<<sample_data_e3>>/>

Make sure to put a leading space or some trailing comment text on any line within the macro that has `\end` by itself. Otherwise the macro definition will end early.

<$codeblock code=<<sample_data_e4>>/>

Another way to display a Card's content is by using the triple-curly-brace inclusion.

<$codeblock code=<<sample_data_e5>>/>

TiddlyWiki\Compare Lines

```
<$diff-text source={{t1}} dest={{mcr glbl_section_disp}}/>
```

Name = mcr glbl_compare_lines

Tag = `$:/tags/Macro`

```
\define glbl_compare_lines_results_table(ur_card_pk, ur_second_pk, ur_row_count)
<table><tr>
<th>''Line''</th>
<th>Show text</th>
<th>First Side<br>Second Side</th>
</tr>
<$list filter="[range<intSECOND_COUNT>subtract[1]]" variable="intCUR_ENTRY">
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]]" variable="strFIRST_LINE">
<$list filter="[{$ur_second_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]!match<strFIRST_LINE>]" variable="strSECOND_LINE">
<tr>
<td rowspan=2>

!!<<intCUR_ENTRY>>
</td>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection1" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine1}!match[]else[0]]" variable=intSTART_LINE><$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_card_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection1"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strFIRST_LINE>> /></td>
</tr>
<tr>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection2" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine2}!match[]else[0]]" variable=intSTART_LINE>
<$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_second_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_second_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection2"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strSECOND_LINE>> /></td>
</tr>
</$list></$list></$list>
</table>
\end
\define glbl_compare_lines(ur_card_pk, ur_second_pk)
<$list filter="[{$ur_card_pk$}splitregexp[\n]count[]]" variable="intFIRST_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]]" variable="intSECOND_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]subtract<intFIRST_COUNT>]" variable="intSECOND_EXTRA">

[[$ur_card_pk$]] line count: <<intFIRST_COUNT>>

[[$ur_second_pk$]] line count: <<intSECOND_COUNT>>

''$ur_second_pk$'' excess line count: ''<<intSECOND_EXTRA>>''

<$macrocall $name=glbl_compare_lines_results_table ur_card_pk="$ur_card_pk$" ur_second_pk="$ur_second_pk$" ur_row_count=<<intSECOND_COUNT>> />
</$list>
</$list>
</$list>
\end

<!--
<$edit-text tiddler="$:/state/popup/CompareText1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>
<$edit-text tiddler="$:/state/popup/CompareText2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>

<<glbl_compare_lines "$:/state/popup/CompareText1" "$:/state/popup/CompareText2">>
-->

TiddlyWiki\Construct a Calendar

```
\define CalendarEntryDay(ur_ymd,ur_d,ur_cur_date)
<$list filter='$ur_ymd$ +[match[$ur_cur_date$]]'>
//''<span style="background-color:yellow">$ur_ymd$</span>''//<br>
</$list>
<$list filter='[prefix[$ur_ymd$]count[]match[0]]'>
<$list filter='$ur_ymd$ +[!match[$ur_cur_date$]]'>
$ur_ymd$<br>
</$list>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]match[1]]">
''d$ur_d$''<br><<currentTiddler>> entry<br>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]!match[0]!match[1]]">
''d$ur_d$''<br><<currentTiddler>> entries<br>
</$list>
\end

\define CalendarEntryMonth(ur_ym,ur_d,ur_cur_date)
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]!match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d0$ur_d$" ur_d="0$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d$ur_d$" ur_d="$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
\end

\define CalendarListDailyThings(day month year)
<$button class='tc-btn-invisible' style='width:100%;height:100%'>
<div style='height:100%;width:100%;position:relative;text-align:left;vertical-align:top;z-index=0'>

<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]!match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_ym="$year$m0$month$" ur_d="$day$"  ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_m="$year$m$month$" ur_d="$day$" ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>


</div>
</$button>
\end
\define date_list_entry(ur_num,ur_cur_date)
<$list filter="[[$ur_num$]match[$ur_cur_date$]]">
//''<span style="background-color:yellow">$ur_cur_date$</span>''//<br>
</$list>
<$list filter="[prefix[$ur_num$]count[]!match[0]]">
<$list filter="[[$ur_num$]!match[$ur_cur_date$]count[]!match[0]]">
$ur_num$<br>
</$list>
</$list>
<<list-links filter:"[prefix[$ur_num$]]" >>
\end
\define date_list_dayunit(ur_num,ur_cur_date)
<$list filter="$ur_num$0 $ur_num$1 $ur_num$2 $ur_num$3 $ur_num$4 $ur_num$5 $ur_num$6 $ur_num$7 $ur_num$8 $ur_num$9">
<$macrocall $name="date_list_entry" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list_daydec(ur_year_month,ur_num,ur_cur_date)
<$list filter="$ur_year_month$d0 $ur_year_month$d1 $ur_year_month$d2 $ur_year_month$d3 $ur_year_month$d4 $ur_year_month$d5 $ur_year_month$d6 $ur_year_month$d7 $ur_year_month$d8 $ur_year_month$d9">
<$macrocall $name="date_list_dayunit" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list(ur_year,ur_month)
<$calendar-month year="$ur_year$" month="$ur_month$" />

<$macrocall $name="date_list_daydec" ur_year_month="$ur_year$m$ur_month$" ur_num=<<currentTiddler>> ur_cur_date=<<now YYYYm0MMd0DD>> />
\end

TiddlyWiki\Core Macro Definition

* Title = `mcr glbl_core_mcr_def`
* Tag = `$:/tags/Macro`

```
\define glbl_core_mcr_def(ur_macro_name)
<$list variable=cur_pk filter="""[[$:/core]get[text]split[define $ur_macro_name$(]butfirst[]split[\n\\end]first[]addprefix[define $ur_macro_name$(]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">
<$codeblock code=<<cur_pk>> />
</$list><!--cur_pk-->
\end
```

* Show all Core macro names and source code

```
<$list variable=show_code_pk filter="[<currentTiddler>split[Draft of]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-checkShowCode]]">
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>

<$list variable=cur_def_text filter="[[$:/core]get[text]split[define ]!prefix[{]!prefix[the]sort[]]">
<$list variable=cur_macro_name filter="[<cur_def_text>split[(]first[]]">
<$list variable=cur_end_text filter="""[<cur_def_text>split[\n\\end]first[]addprefix[define ]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">

!! <<cur_macro_name>>
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]match[yes]]"><$codeblock code=<<cur_end_text>> />
</$list><!--cur_showcode_text-->

</$list><!--cur_end_text-->
</$list><!--cur_macro_name-->
</$list><!--cur_def_text-->
</$list><!--show_code_pk-->
```

TiddlyWiki\CSS Classes

!! New Card page
* Card name = css alternating-rows
* Tag = $:/tags/Stylesheet

```
.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}
```

Note: The @''''@ directive must include the leading period (.) to select a CSS class

```
@@.alternating-rows
<table>
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

TiddlyWiki\CSS without classes

!! Apply stylesheet to all cards

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
.tc-tiddler-body {
  word-break: normal; 
  word-wrap: break-word;
  white-space: pre-wrap;
} 
```

* Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

!! Apply stylesheet to cards with specific tag `linewrap`

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

* Note: Only cards with the `linewrap` tag will use this stylesheet change

!! Apply Styles to In-line Text

* Start a text block with @,,,,@ and the CSS styles with no spaces

Sample Code:

```
@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line
```

<<<
Result:

```
These are
separate lines
here

This is one big line
```
<<<

* or start in the middle of a text block

Sample Code:

```
This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.
```

<<<
Result:

```
This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.
```
<<<

TiddlyWiki\Data Tiddler

Type = `application/x-tiddler-dictionary`

```
3:a
2:b
3:c
```

See list of unique indexes:

```
<$list variable=cur_key filter="[[UrPK]indexes[]]"><<cur_key>>: 
<$list variable=cur_val filter="[[UrPK]getindex<cur_key>]"><<cur_val>><br>
</$list><!--cur_val-->
</$list><!--cur_key-->
```

Use one value (last one if an index is duplicated):

```
-{{UrPK##3}}-


```

[[VBNetCode\Text file to JSON Lines]]

TiddlyWiki\Date Part

Tag = `$:/tags/Macro`

```
\define glbl_dt_ddd()
<div style="clear:right;float:right;background-color:aquamarine;"><<now "YYYYm0MMd0DD DDD pm0hh12\m0mm">></div>
<$list filter="[<currentTiddler>split[Draft of ']join[]split[ ]first[]split[m]join[]split[d]join[]]">
<$view field="title" format="date" template="[UTC]DDD" />
</$list>
\end
```

|!Token |!Substituted Value |
|`DDD` |Day of week in full (eg, "Monday") |
|`ddd` |Short day of week (eg, "Mon") |
|`DD` |Day of month |
|`0DD` |Adds a leading zero |
|`DDth` |Adds a suffix |
|`WW` |ISO-8601 week number of year |
|`0WW` |Adds a leading zero |
|`MMM` |Month in full (eg, "July") |
|`mmm` |Short month (eg, "Jul") |
|`MM` |Month number |
|`0MM` |Adds leading zero |
|`YYYY` |Full year |
|`YY` |Two digit year |
|`wYYYY` |Full year with respect to week number |
|`wYY` |Two digit year with respect to week number |
|`hh` |Hours |
|`0hh` |Adds a leading zero |
|`hh12` |Hours in 12 hour clock |
|`0hh12` |Hours in 12 hour clock with leading zero |
|`mm` |Minutes |
|`0mm` |Minutes with leading zero |
|`ss` |Seconds |
|`0ss` |Seconds with leading zero |
|`XXX` |Milliseconds |
|`0XXX` |Milliseconds with leading zero |
|`am` or `pm` |Lower case AM/PM indicator |
|`AM` or `PM` |Upper case AM/PM indicator |
|`TZD` |Timezone offset |
|`\x` |Used to escape a character that would otherwise have special meaning |
|`[UTC]`|Time-shift the represented date to UTC. Must be at very start of format string|

TiddlyWiki\Decimal To Hex

"""
Name = mcr glbl_dec_to_hex5
Tag = `$:/tags/Macro`
"""

```
\define glbl_dec_to_hex5(ur_code)
<$list filter="[[$ur_code$]divide[16]divide[16]divide[16]divide[16]floor[]]" variable=lvl_x4>
<$list filter="[<lvl_x4>multiply[16]multiply[16]multiply[16]multiply[16]]" variable=lvl_d4>
<$list filter="[[$ur_code$]subtract<lvl_d4>divide[16]divide[16]divide[16]floor[]]" variable=lvl_x3>
<$list filter="[<lvl_x3>multiply[16]multiply[16]multiply[16]]" variable=lvl_d3>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>divide[16]divide[16]floor[]]" variable=lvl_x2>
<$list filter="[<lvl_x2>multiply[16]multiply[16]]" variable=lvl_d2>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>divide[16]floor[]]" variable=lvl_x1>
<$list filter="[<lvl_x1>multiply[16]]" variable=lvl_d1>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>subtract<lvl_d1>]" variable=lvl_xrem>
<$list filter="[range[15]butfirst[9]match<lvl_x4>add[55]] [range[10]subtract[1]match<lvl_x4>add[48]]" variable=lvl_h4>
<$list filter="[range[15]butfirst[9]match<lvl_x3>add[55]] [range[10]subtract[1]match<lvl_x3>add[48]]" variable=lvl_h3>
<$list filter="[range[15]butfirst[9]match<lvl_x2>add[55]] [range[10]subtract[1]match<lvl_x2>add[48]]" variable=lvl_h2>
<$list filter="[range[15]butfirst[9]match<lvl_x1>add[55]] [range[10]subtract[1]match<lvl_x1>add[48]]" variable=lvl_h1>
<$list filter="[range[15]butfirst[9]match<lvl_xrem>add[55]] [range[10]subtract[1]match<lvl_xrem>add[48]]" variable=lvl_hrem>
<$wikify name=str_hex_out text="0x&#<<lvl_h4>>;-&#<<lvl_h3>>;&#<<lvl_h2>>;&#<<lvl_h1>>;&#<<lvl_hrem>>;" >
<<str_hex_out>>
</$wikify>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
\end

TiddlyWiki\Delete All Cards with Tag

```
<$button>
<$list filter="[tag[ARTICLE]]"><$action-sendmessage $message=tm-delete-tiddler $param=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards with Confirmation
</$button>

<$button>
<$list filter="[tag[ARTICLE]]"><$action-deletetiddler $tiddler=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards without Confirmation
</$button>

<$button>
<$list filter="[tag[DOC]]" variable=doc_pk><$list filter="[<doc_pk>fields[]prefix[e]]" variable=field_pk2><$action-deletefield $tiddler=<<doc_pk>> $field=<<field_pk2>> /></$list></$list>
Del fields starting with `E` in DOC tagged Cards
</$button>

TiddlyWiki\DivPop btn

[[DivPop.svg]]

Tag = `$:/tags/ViewToolbar`

```
\define divpop_current(ur_ref)
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text="$ur_ref$"/>
<$action-sendmessage $message="tm-close-tiddler" $param="pop_right"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{DivPop.svg}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text="Popup over Sidebar"/></span>
</$list>
</$button>
\end

<$list filter="[all[current]]">
<$macrocall $name=divpop_current ur_ref=<<currentTiddler>> /> 
</$list>

TiddlyWiki\DivPop glbl

Tag = `$:/tags/BelowStory`

```
<$list filter="[{$:/state/popup/DivPopTitle}is[tiddler]]">
<div style="
position: fixed;
top: 0px;
right: 0px;
width: 350px;
border: 3px solid;
background: white;
bottom: 0%;
">
<div style="overflow-y: scroll; height: 100%;">
<$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
close
</$button>
<$tiddler tiddler=<<currentTiddler>> >
<$transclude mode="block" />
</$tiddler>
</div>
</div>
</$list>

TiddlyWiki\Embed Font

"""
[https://tiddlywiki.narkive.com/bS0CgWKQ/tw-tw5-how-to-embed-a-font-using-font-face-and-data-url]
- Visit: http://www.fontsquirrel.com/tools/webfont-generator
- Upload your font file (".ttf", ".eot", ".woff", etc)
- Select option "Expert"
- Check the option case at CSS >> Base64 Encode
- Generate your webkit -> Downloads file

[stylesheet.zip file]
- Unpack ZIP file -> Downloads file

[stylesheet.css]
- Note: The file's content in Base64 encoded

[Wiki file]
- Drag-drop file to import -> Creates Card
- [styleshee.css Card]
- Make sure the field font-family is what you want
- Tag = $:/tags/Stylesheet
- Tiddler type = Plain text (text/plain)
- Create a new Card and use the font

TiddlyWiki\Encrypt file

"""
[Wiki file]
- [Sidebar, Tools tab]
- Click button Set Password -> Opens dialog
- Password = UrPasswordText
- Repeat password = UrPasswordText
- Click button Set Password -> Closes dialog

[keyboard action SaveAllChanges]
- [<$action-sendmessage $message="tm-download-file"]
- Comment out this tag to keep the HTML Wiki version from being exported
- Save the Wiki file

- Note: The password will be required to start the Wiki application when you open the Wiki file

TiddlyWiki\External Link organization

* Create one Card for each external link in this format
** Title always starts with `ext` and a space, then the external link description
** Tagged as EXT
** Contains one line in this format:

```
[ext[ur_url]]
```

* Reference the Card with the `ext` macro, but don't include the `ext` prefix or the leading space
* The link is shown, and there will be `->` on the right side of the Card window
* This flags links that will open in a new tab, and allows you to easily open the `ext` Card and change the saved link

```
<<ext "UrExternalLinkDiscption">>
```

* Global macro
** Title = mcr glbl_ext
** Tag = $:/tags/Macro
** Main Body text =

```
\define ext(ur_extcard_pk)
{{ext $ur_extcard_pk$}}<div style="float:right">[[_|ext $ur_extcard_pk$]]</div>
\end

TiddlyWiki\Filter Operators

!!Math

"""
abs - calculate the absolute value of a list of numbers
add - treating each input title as a number, add to each the numeric value of the operand
ceil - rounds a list of numbers up to the next largest integer
divide - treating each input title as a number, divide them by the numeric value of the operand
exponential - convert each number to exponential notation with N digits
fixed - convert each number to fixed point notation with N digits after the decimal point
floor - rounds a list of numbers to the largest integer less than or equal to each number
max - treating each input title as a number, take the maximum of its value and the numeric value of the operand
maxall - find the largest of a list of numbers
min - treating each input title as a number, take the minimum of its value and the numeric value of the operand
minall - find the smallest of a list of numbers
multiply - treating each input title as a number, multiply it by the numeric value of the operand
negate - calculate the negation of a list of numbers
precision - convert each number to a string with N significant digits
product - produce the product of the input numbers
remainder - treating each input title as a number, return the remainder when divided by the numeric value of the operand
round - rounds a list of numbers to the nearest integer
sign - return -1, 0 or 1 for a list of numbers according to whether each number is negative, zero, or positive
subtract - treating each input title as a number, subtract from each the numeric value of the operand
sum - produce the sum of the input numbers
trunc - truncates a list of numbers to their integer part, removing any fractional part
untrunc - rounds a list of numbers to the next integer with largest absolute value, that is, away from zero

TiddlyWiki\Fonts via URL

```
<link href='https://fonts.googleapis.com/css?family=Playfair Display' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Sofia' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Alex Brush' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Akronim' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Annie Use Your Telescope' rel='stylesheet'>

@@font-family: 'Playfair Display';
!'Playfair Display'  1234567890 ABC abc
@@

@@font-family: 'Sofia';
!'Sofia'  1234567890 ABC abc
@@

@@font-family: 'Alex Brush';
!'Alex Brush'  1234567890 ABC abc
@@

@@font-family: 'Akronim';
!'Akronim'  1234567890 ABC abc
@@

@@font-family: 'Annie Use Your Telescope';
!'Annie Use Your Telescope'  1234567890 ABC abc
@@

TiddlyWiki\Global Card Footer

Every Card shows the Wikified content of the Card content, followed by the Wikified content of every Card with the tag `$:/tags/ViewTemplate`.

!Example Footer Text

Create a new Card

<<<
template Global Footer
<<<

```
Any Text Here
```

Add the tag:

* $:/tags/ViewTemplate

And then every Card will show the words "Any Text Here" at the bottom of the Card.

!Example Footer Home Button

Create a new Card

<<<
template Home Button
<<<

```
<div style="float:right">{{$:/core/ui/Buttons/home}}</div>
```

Add the tag:

* $:/tags/ViewTemplate

And then every Card will show the "Home" icon at the bottom-right of the Card.



TiddlyWiki\Global Macro

Tag = `$:/tags/Macro`

TiddlyWiki\Group Totals

```
unique_groups()
- find list of titles with UrAttribute
    - [has[UrAttribute]]
- split by the prefix before the first hyphen
    - [<currentTiddler>split[-]nth[1]]
- return each title's prefix followed by a space
    - ><<currentTiddler>> <

unique_counts()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces
    - [<ugrp>split[ ]
- ignore white-space only entries, and sort the rest alphabetically
    - !match[]sort[]
- use "each:value" to get the unique title prefixes in the list
    - each:value[]]
- for each unique title prefix, get a count of titles with UrAttribute
    - [has[UrAttribute]prefixcount[]]

count_size()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces, ignore white-space, sort, use "each:value", store as ur_entry
    - [<ugrp>split[ ]!match[]sort[]each:value[]]
    - ur_entry=<<currentTiddler>>
- for each unique title prefix, only continue where the count of titles with UrAttribute matches the parent unique count
    - [has[UrAttribute]prefix<ur_entry>count[]match[$(currentTiddler)$]]
- find all the titles with the unique title prefix, and return a "1" for each entry
    - [has[UrAttribute]prefix]">1 <

main()
- create a new variable ucnt with the list of title prefixes from unique_counts()
    - <$wikify name=ucnt text=<<unique_counts>>
- split the new variable by spaces, ignore white-space, sort, use "each:value"
    - [split[ ]trim[]!match[]sort[]each:value[]]
- For each unique count,
    - list the entry
    - sum the number of entries returned from count_size() divided by the unique count
```

```
\define unique_groups()
<$list filter="[has[eng-vocab]]"><$list filter="[<currentTiddler>split[-]nth[1]]"><<currentTiddler>> </$list></$list>
\end
\define unique_counts()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]">
<$list filter="[has[eng-vocab]prefix<currentTiddler>count[]]"><<currentTiddler>> </$list>
</$list>
</$wikify>
\end
\define count_size()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]"><$vars ur_entry=<<currentTiddler>> >
<$list filter="[has[eng-vocab]prefix<ur_entry>count[]match[$(currentTiddler)$]]">
<$list filter="[has[eng-vocab]prefix<ur_entry>]">1 </$list>
</$list>
</$vars></$list>
</$wikify>
\end
<$wikify name=ucnt text=<<unique_counts>> >
<$list filter="[<ucnt>split[ ]trim[]!match[]sort[]each:value[]]">
ASLSJ Prefix Groups with <<currentTiddler>> words -
<$wikify name=usize text=<<count_size>> >
<$list filter="[<usize>split[ ]trim[]!match[]sum[]divide<currentTiddler>]"><<currentTiddler>><br>
</$list>
</$wikify>
</$list>
</$wikify>
```

TiddlyWiki\Hard Line Breaks

HTML normally ignores line breaks. TiddlyWiki uses HTML, and includes a way to stop ignoring line breaks.

[TiddlyWiki editor]
- Type three double-quotes (`"""`) and press enter to ignore line breaks below this point
- The (`"""`) does not show up in the output

Three double-quotes will start a hard line breaks section

```
"""
```

```
line one blends into line two continues

"""
line three stops
line four starts
"""
```

line one blends into
line two continues

"""
line three stops
line four starts
"""

!!HTML Preformatted text with Sans-Serif font

`<pre style="font-family: sans-serif;">line three stops
line four starts</pre>`

<pre style="font-family: sans-serif;">line three stops
line four starts</pre>

TiddlyWiki\Hidden on Static File

!! Hide section when exported to static HTML file

```
<$list filter="[<tv-config-toolbar-icons>match[no]]">
```

TiddlyWiki\iFrame

Use an iFrame to run JavaScript in a TiddlyWiki

```
>iframe src="javascript:newWindow='';var ...
```

- just `javascript:newWindow=var ...` did not compile. An empty string is a work-around.

Alternative output: use alert instead of document.write

```
alert(strTEXT);"/>
```

How to reference an external HTML file in a tiddler

```
>iframe src=...  scrolling=yes style="border-style:none;height:100%;width:100%">
>/iframe>
```

- A self-closing tag does not allow remaining html code to be displayed
- ALWAYS specify a closing >/iframe> tag

TW Macro to show iframe and link

```
>div style='float:right'>[ext[_ |$ur_pk$.txt.html]]
>/div>
>iframe src='$ur_pk$.txt.html'>
>/iframe>
```

- $macrocall $name=iframe_txt ur_pk= currentTiddler

```
<iframe src="javascript:newWindow='';var qs = '&quot;';var qt = '&apos;';

var objFRAME = document.createElement('iframe');
objFRAME.setAttribute('id', 'innerFrame');
objFRAME.setAttribute('src', 'http://www.google.com/');
document.body.appendChild(objFRAME); 
var objTEST = objFRAME;
var strTEXT = '';
if (objTEST===undefined) {
strTEXT = 'undef obj';
} else if (objTEST===null) {
strTEXT = 'null obj';
} else {
var intSEQ = 0;
var strNAME;
for (strNAME in objTEST) {
intSEQ += 1;
strTEXT += ' ; ' + strNAME;
}
strTEXT = 'olen ' + intSEQ + strTEXT;
}
document.write(strTEXT);"></iframe>

alert(strTEXT);"/>

<iframe src='iframe.scrE2.txt' height=100% width=100% scrolling=yes frameborder=no></iframe>


\define iframe_txt(ur_pk)
<div style="float:right">[ext[_ |$ur_pk$.txt.html]]</div>
<iframe src='$ur_pk$.txt.html' scrolling=yes style="border-style:none;height:100%;width:100%"></iframe>
\end

TiddlyWiki\Ignore WikiText formatting

!! Use the TextWidget to ignore WikiText formatting

* widget name = `$text`
* `text` attr = <$text text="`still black colored text`" />

!! Sample code

```
<$text text="`still black colored text`" />
```

<<<
Results:

<$text text="`still black colored text`" />
<<<
!! Use the Rules card pragma to ignore WikiText formatting

* [New card]
* Put `\rules only` at the top of the card text

!! Sample code

```
\rules only
`still black colored text`
```

<<<
Results:

<$text text="`still black colored text`" />
<<<

!! Use the Card Datatype to ignore WikiText formatting

* [New card]
* `type` field = `text/plain`

!! Sample code

```
`still black colored text`
```

<<<
Results:

```
`still black colored text`
```
<<<

TiddlyWiki\Image

"""
Link an image in a Tiddler with 500px width
- Have image tiddler
- Have text tiddler
- Apply image to text tiddler at 500px width

[New tiddler]
- title = mcr img_link
- tag = $:/tags/Macro
- text field code
"""

```
\define img_link(ur_pk)
@@max-width:500px;
[img [$ur_pk$]]
@@
\end
```

"""
[Text tiddler]
- $macrocall $name=img_link ur_pk= currentTiddler
"""

TiddlyWiki\Image link opens Card

Tag = `$:/tags/Macro`

```
\define glbl_image_high(ur_image_pk, ur_size:200)
<$link to="$ur_image_pk$">[img height=$ur_size$px [$ur_image_pk$]]</$link>
\end
\define glbl_image_wide(ur_image_pk, ur_size:500)
<$link to="$ur_image_pk$">[img width=$ur_size$px [$ur_image_pk$]]</$link>
\end

TiddlyWiki\Import Macros

```
\import [[mcr date_list]]

TiddlyWiki\Javascript Calculation in Bookmarklet

* Click the button to copy the text to a javascript bookmarklet
* Open a new tab
* Type the letter "j" in the address bar, paste in the clipboard text, and press enter
* The Javascript alert box shows the message

```
\define glbl_copyto_js_bookmarklet(ur_js_code)
<pre>$ur_js_code$</pre>
<$macrocall $name="copy-to-clipboard" src="""avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){const el = newWindow.document.createElement('textarea');const ur_str='$ur_js_code$';try {el.value =eval(ur_str)}catch(err) {el.value = err.message;}; newWindow.document.body.appendChild(el); el.select();void(newWindow.focus());}""" />
\end

<!--|v
<<glbl_copyto_js_bookmarklet """parseInt("FF",16).toString(10);""">>
^|-->

TiddlyWiki\Keep words together on one line

!! Use CSS white-space tag

* The CSS `white-space:nowrap;` disables normal text wrapping
* This is useful when you have several smaller phrases that should not be separated visually onto different lines
* Note: This can make the line extend past the edge of the browser window, requiring scrolling to see the rest

!!Sample Code that can split phrases

```
A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)
```

<<<
Results:

A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)
<<<

!!Sample Code that can keeps short phrases together

```
@@white-space:nowrap;A code line (1)@@ @@white-space:nowrap;A code line (2)@@ @@white-space:nowrap;A code line (3)@@ @@white-space:nowrap;A code line (4)@@ @@white-space:nowrap;A code line (5)@@ @@white-space:nowrap;A code line (6)@@ @@white-space:nowrap;A code line (7)@@ @@white-space:nowrap;A code line (8)@@ @@white-space:nowrap;A code line (9)@@ @@white-space:nowrap;A code line (10)@@ @@white-space:nowrap;A code line (11)@@ @@white-space:nowrap;A code line (12)@@ @@white-space:nowrap;A code line (13)@@ @@white-space:nowrap;A code line (14)@@
```

<<<
Results:

@@white-space:nowrap;A code line (1)@@ @@white-space:nowrap;A code line (2)@@ @@white-space:nowrap;A code line (3)@@ @@white-space:nowrap;A code line (4)@@ @@white-space:nowrap;A code line (5)@@ @@white-space:nowrap;A code line (6)@@ @@white-space:nowrap;A code line (7)@@ @@white-space:nowrap;A code line (8)@@ @@white-space:nowrap;A code line (9)@@ @@white-space:nowrap;A code line (10)@@ @@white-space:nowrap;A code line (11)@@ @@white-space:nowrap;A code line (12)@@ @@white-space:nowrap;A code line (13)@@ @@white-space:nowrap;A code line (14)@@
<<<

TiddlyWiki\Keyboard Shortcut

!!Pre-requisites

* You need a `ur_message_to_send` to replace in the below steps
** `tm-home` is an example message that TiddlyWiki can do
* You need a `ur_card_pk` to replace in the below steps
** It should describe the desired action

!!Setup keyboard shortcut

[New Card]

* Title = $:/config/ShortcutInfo/ur_card_pk
* Main Body text is blank

[New Card]

* Title = $:/config/shortcuts/ur_card_pk
* Main Body Text =

```
alt-H
```

[New Card]

* Title = keyboard action ur_card_pk
* Tag = $:/tags/KeyboardShortcut
* Field-Value: key =

```
((ur_card_pk))
```

* Main Body Text =

```
<$action-sendmessage $message="ur_message_to_send"/>
```

TiddlyWiki\List Links from Numbered Fields

```
<ol>
<$list filter="[<currentTiddler>fields[]prefix[e]sort[]]" variable=lookup_name>
<$list filter="[<currentTiddler>get<lookup_name>]" variable=ref_card_pk>
<$list filter="[<ref_card_pk>get[img]else[]]" variable=ref_img_pk>
<li><$link to=<<ref_card_pk>> />@@float: right;overflow: auto;vertical-align: top;padding-left: 10px;<$image width=200px source=<<ref_img_pk>> />@@<div style="clear:both;"></div></li>
</$list>
</$list>
</$list>
</ol>

TiddlyWiki\List Links of Prefixed Cards

```
<ol>
<$list filter="[<currentTiddler>addsuffix[\]]">
<$list filter="[all[tiddlers]prefix<currentTiddler>sort[]]">
<li><$link to=<<currentTiddler>> /></li>
</$list>
</$list>
</ol>

TiddlyWiki\List Links standard

```
<<list-links filter:"[tag[DOC]field:level[1]sort[title]] [tag[DOC]field:level[]sort[title]]">>

TiddlyWiki\List Widget

! Content and Attributes

The content of the `<$list>` widget is an optional template to use for rendering each tiddler in the list.

The action of the list widget depends on the results of the filter combined with several options for specifying the template:

* If the filter evaluates to an empty list, the text of the ''emptyMessage'' attribute is rendered, and all other templates are ignored
* Otherwise, if the ''template'' attribute is specified then it is taken as the title of a tiddler to use as a template for rendering each item of the list
* Otherwise, if the list widget content is not blank, it is used as a template for rendering each item of the list
* Otherwise, a default template is used consisting of a `<span>` or `<div>` element wrapped around a link to the item

|!Attribute |!Description |
|filter |The [[tiddler filter|Filters]] to display |
|template |The title of a template tiddler for transcluding each tiddler in the list. When no template is specified, the body of the ListWidget serves as the item template. With no body, a simple link to the tiddler is returned. |
|editTemplate |An alternative template to use for [[DraftTiddlers|DraftMechanism]] in edit mode |
|variable |The name for a [[variable|Variables]] in which the title of each listed tiddler is stored. Defaults to ''currentTiddler'' |
|emptyMessage |Message to be displayed when the list is empty |
|storyview |Optional name of module responsible for animating/processing the list |
|history |The title of the tiddler containing the navigation history |

!! Additional Notes and Edge Cases

* If the `filter` attribute is not present then a default of `[!is[system]sort[title]]` is used
* If the list widget is completely empty (ie only whitespace between the opening and closing tags), then it behaves as if the content were a `DIV` or a `SPAN` containing a link to the current tiddler (it’s a `DIV` if the list widget is in block mode, or a SPAN if it is in inline mode)
* If the `template` attribute is not present then the content of the list widget will be used as the template, unless the widget is completely empty in which case a default template is used

TiddlyWiki\Local Video or Audio Files

```
<video width="320" height="180"
poster="video\Frozen Sleep - Cortana Tribute by Malukah.png"
controls preload="none">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.webm" type=
"video/webm">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.ogv" type=
"video/ogg">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.mp4" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
```

```
<audio controls preload="none">
<source src="audio\Frozen-Sleep-Malukah.ogg" type="audio/ogg">
<source src="audio\Frozen-Sleep-Malukah.mp3" type="audio/mp3">
<p>Your browser does not support the HTML 5 audio tag.</p>
</audio>
```

TiddlyWiki\Pagination

```
\define page_next()
<$list variable="filter_prev_page" filter="[<page_pk>get[text]!match[0]!match[]]">
<$button style="margin-left:30px">
<$action-setfield $tiddler=<<page_pk>> text=""/>
First page
</$button>

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>subtract[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/></$list>
Previous page
</$button>
</$list><!--filter_prev_page-->

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>add[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/><$action-navigate $to=<<card_pk>> $scroll="yes"/></$list>
Next page
</$button><br>
<!--***page_next***-->
\end
<$list variable="card_pk" filter="[<currentTiddler>]">
<$list variable="popup_pk" filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]">

<$list variable="page_pk" filter="[<popup_pk>addsuffix[-cur_page]]">
<$list variable="cur_page_skip" filter="[<page_pk>get[text]!match[]else[0]]">
<$list variable="cur_page_num"filter="[<cur_page_skip>add[1]]">
<$list variable="cur_page_through" filter="[<cur_page_num>subtract[1]add[10]]">
<<page_next>>

<$list variable="subdir_count" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]count[]]">

Subdirectories <<cur_page_num>> through <<cur_page_through>>

Number of subdirectories: <<subdir_count>><br>
<$list variable="cur_subdir_path" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]butfirst<cur_page_num>first[10]]">

<$list variable="raw_image_count" filter="[{File List Data}splitregexp[\n]prefix<cur_subdir_path>uppercase[]suffix[.JPG]count[]addprefix[ (]addprefix<cur_subdir_name>addsuffix[ photo]]">
<<raw_image_count>>
</$list><!--raw_image_count-->

</$list><!--cur_subdir_path-->
</$list><!--subdir_count-->
<<page_next>>
</$list><!--cur_page_through-->
</$list><!--cur_page_num-->
</$list><!--page_pk-->
</$list><!--popup_pk-->
</$list><!--card_pk-->

TiddlyWiki\Popup State Clear All

```
<$list filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]" variable="popup_pk">
<$button>
<$list filter="[all[tiddlers]prefix<popup_pk>has[text]]" variable=del_pk><$action-deletefield $tiddler=<<del_pk>> $field="text"/></$list>
Show All
</$button><br>

</$list>

TiddlyWiki\Published Tools

https://dynalist.io/d/zUP-nIWu2FFoXH-oM7L7d9DM#z=zdF80rIaJ79W5P0IGsjYIjkD

"""
[Ace editor](http://innoq.tiddlyspot.com/)
[ActionIncrement widget](https://skeeve.github.io/tw5-plugins/) - The action-increment widget is an action widget that retrieves a value from a text reference. It will then increase the first digit-sequence found in that text and store it.
[Ad-Hoc Macro](https://tobibeer.github.io/tb5/#Ad-Hoc%20Macro) - evaluate any text as an ad-hoc macro even passing variables.
[Amazon Web Services Plugin](https://tiddlywiki.com/#OfficialPlugins) - provides several tools for working with Amazon Web Services **(official TW plugin)**
[Delay Actions](https://groups.google.com/forum/#!topic/tiddlywiki/z7SGLAPODW8), defer the execution of action widgets for a set amount of time
[CouchDB adaptor](https://github.com/wshallum/couchadaptor)
[Count (tobibeer)](http://tobibeer.github.io/tw5-plugins/#count) - A filter to count titles or compare against a specified count
[Demo Code Macro](http://ooktech.com/jed/ExampleWikis/DemoCodeMacro/) - This is an attempt to make a macro that can be used to demonstrate wikitext code fragments in an interactive way.
[dom (tobibeer)](http://tobibeer.github.io/tw5-plugins/#dom) - retrieve text or attributes from dom nodes
[eval (tobibeer)](http://tobibeer.github.io/tw5-plugins/#eval) - Evaluate expressions, compute and compare tiddler properties and data
[Fargo.io integration](http://blog.jeffreykishner.com/2014/01/24/note-taking-bookmarklets-for-fargoio-and-tiddlywiki-.html)
[Global macros, instructions on how to make](http://tw5magick.tiddlyspot.com/)
[Highlight plugin](https://tiddlywiki.com/plugins/tiddlywiki/highlight/#%24%3A%2Fplugins%2Ftiddlywiki%2Fhighlight) **(official TW plugin)** - description: Plugin that activates syntax highlighting of code blocks using v8.8.0 of highlight.js from Ivan Sagalaev. demo [here](https://tiddlywiki.com/plugins/tiddlywiki/highlight/)
[HTAlink](http://welford.github.io/) - Will only work in offline hta editions of this page. Launches external links in your default browser and not IE
[ifAisB](https://tid.li/tw5/hacks.html) - This macro allows to test if a value A – a variable or a transcluded value – matches a value B and to react accordingly. It works almost like an if-then-else statement.
[IfTid Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the existence of a tiddler (or field) and to send different widget messages based upon the existence of this tiddler (or field.) 
[IfTref Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the value of a TextReference and to send different widget messages based upon whether this value matches the value specified by the 'value=' attribute.
[Incremental load command](http://malsandbox.tiddlyspot.com/) - only loads tiddlers that either don't already exist in the tiddlers folder, or have a newer modified date than the existing tiddler.
[Javascript macros in wikitext](http://tw5magick.tiddlyspot.com/)
[JSON editor (btheado)](http://btheado.github.io/jsoneditor.html)
[JSON editor (bjtools)](http://bjtools.tiddlyspot.com/)
[JsonMangler](https://joshuafontany.github.io/TW5-JsonMangler/) - This plugin changes the methods tiddlywiki uses to retrieve and set values in json data tiddlers. It does this in a way that aims for backwards compatibility.

[keyboard-snippets plugin](http://braintest.tiddlyspot.com/#keyboard-snippets)
[LetWidget](http://tiddlystuff.tiddlyspot.com/) - The LetWidget is an enhancement of the SetWidget.
[mforth](https://quaraman.de/tw/mforth.html) - It is a forth like language in a tiddlywiki macro. Forth operates with Reverse Polish Notation (RPN for short).
[Mousetrap](http://welford.github.io/) - simple library for handling keyboard shortcuts in Javascript.
[muut integration](http://ooktech.com/jed/ExampleWikis/TiddlyWiki-muut/)
[Nodewebkitsaver plugin](http://ooktech.com/jed/ExampleWikis/SetFilters/#%24%3A%2Fplugins%2FOokTech%2FSetFilters) - provides a saver module for saving changes when using [TiddlyWiki](http://ooktech.com/jed/ExampleWikis/SetFilters/#TiddlyWiki) directly under NW.js (previously known as node-webkit).
[Pack as plugin](http://braintest.tiddlyspot.com/#Pack%20as%20plugin) - Beta version
[Pan widget](http://muritest.tiddlyspot.com) - This widget is touch sensitive. It is able to trigger actions as the start and end of pans. Multiple differntial pans are possible.
[Persistent-states](https://wikilabs.github.io/#persistent-states) and [Remove-states](https://wikilabs.github.io/#remove-states)
[pick Plugin](https://skeeve.github.io/tw5-plugins/) - The pick plugin is a set of two filters and one widget to help extracting data from your TiddlyWiki file.
[PluginSize](https://tid.li/tw5/plugins.html#%24%3A%2Fplugins%2Ftelmiger%2FPluginSize:%24%3A%2Fplugins%2Ftelmiger%2FPluginSize) - This plugin calculates the size of all installed plugins, including themes and languages.
[PluginDevelopment](https://github.com/inmysocks/PluginDevelopment) -- Scripts to help you create plugins and plugin libraries for node.js
[pv5](http://pv5.tiddlyspot.com/) - testing params and variables
[random (tobibeer)](http://tobibeer.github.io/tw5-plugins/#random) - A filter to return one or more random titles
[ReplacePragma](http://tiddlystuff.tiddlyspot.com/)
[Save trail plugin](https://tiddlywiki.com/#OfficialPlugins) - This plugin causes TiddlyWiki to continuously download (as a JSON file) the contents of any tiddler that is manually changed by any of several means **(official TW plugin)**
[setvars (tobibeer)](http://tobibeer.github.io/tw5-plugins/#setvars) - Set multiple, complex variables based on attributes, filters, or conditionals
[Shuffle filter operator](https://mklauber.github.io/tw5-plugins/#Shuffle%20Operator) - implements a new filter operator called Shuffle. This operator takes the input list and randomizes the order of the list. If no parameter is provided, the list order is random every time.
[SPilot4Tw](https://www.quaraman.de/tw/pilot.html) - A programming language that can be included as Tiddlywiki plugin.
[Startup Actions demo](http://ooktech.com/jed/ExampleWikis/StartupActions/) - A plugin to add startup scripts to TiddlyWiki 
[style (tobibeer)](http://tobibeer.github.io/tw/style/#GettingStarted) - This wiki introduces you to using your desktop browser to inspect the styles applied to elements in TiddlyWiki and permanently change them.
[Three.js](http://rboue.tiddlyspot.com/#Three.js%2Fintroduction) - 3D modeling
[TiddlyWiki5 Coding](http://cjhunt.github.io/) - These pages document aspects TiddlyWiki5 programming, sharing "lessons learned" to help developers to get started with TiddlyWiki5 customization and extension. (FYI - 4 years old)
[Tinka](https://tinkaplugin.github.io/) - Create and modify plugins in the browser. 
[Trace-variable example](http://eucaly-tw5.tiddlyspot.com/#trace-variable%20Example) - no clue what this is.
[Trigger Actions Demo](http://ooktech.com/jed/ExampleWikis/TriggerActions/)
[Tutorial Maker with HopScotchjs](https://cdn.rawgit.com/abesamma/TW5-tutorial-maker-plugin/29c31124/Demo.html) - a plugin that allows TW5 developers to create interactive product tutorials for their tiddlywiki projects, to guide new users.
[TW Components](https://tw-scripts.github.io/TW-Components/) - A component is a group of TW macros and tiddlers create a visual element for complex processes. The ultimate objective of TW components is to create objects which can simply by used by TW programmer to create complex plugins or codes.
[twexe - run exe's from hta files](https://github.com/welford/twexe) - only works in offline hta versions of TW. It lets you register and run exes from tiddlywiki

TiddlyWiki\Recently Changed Cards

```
<<timeline limit:30 format:"YYYY-0MM-0DD">>

TiddlyWiki\Regular Expression

```
<!--|v
Split at Regular Expression skips everything before the first period -> `.12`,  `.1` and `.or.maybe.1`
^|-->

<$vars re="^[^\.]*">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>

<!--|v
Split at Regular Expression skips everything before the last period -> `1`,  `1` and `1`

Each:Value gets the unique list of entries -> `2` and `1`

Sort orders them numberically
^|-->

<$vars re="^.*\.">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>!match[]each:value[]sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>


<!--|v
Split
^|-->

<!--<$vars re="^[^\.]*"> skip up to first period excluded-->
<!--<$vars re="^.*\."> skip up to first period included-->
<$vars card_pk="File List Data" re="^.*\.">
<$list variable="cur_file_ext" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.gif(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.jpeg(?i)]] [<card_pk>get[text]splitregexp[\n]regexp[\.jpg$(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.png(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.tif(?i)]] +[splitregexp<re>!match[]each:value[]sort[]addprefix[.]]">
<$list variable="file_ext_count" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]suffix<cur_file_ext>count[]]">

<<cur_file_ext>>: <<file_ext_count>> files
</$list><!--file_ext_count-->
</$list><!--cur_file_ext-->
</$vars>

TiddlyWiki\Reveal Section and Copy Data

Title = mcr T1Reveal

```
\define t1cb(UrContent)
<$list filter="[[$UrContent$]!match[]]">
$UrContent$
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
\end
\define t1reveal(UrPK UrSeq UrContent)
<$list filter="[[$UrContent$]!match[]]">
<br>
<$reveal type="nomatch" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="show">,,$UrSeq$,,</$button>
</$reveal>
<$reveal type="match" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="hide">^^$UrSeq$^^</$button><br>
"""
$UrContent$
"""
</$reveal>
<$list filter="[[$UrSeq$]match[Pwd]]">
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
</$list>
\end

TiddlyWiki\Save Wiki and Export HTML

```
\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.htm"
/>
<$action-sendmessage $message="tm-download-file"
$param="$:/core/templates/exporters/StaticRiver" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
exportFilter="""[all[tiddlers]tag[INDEX]sort[title]][all[tiddlers]!tag[EXTLINK]!tag[INDEX]!tag[META]!prefix[Draft of]!is[image]!is[tag]!is[system]sort[title]]"""/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.htm]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>

TiddlyWiki\Search all Fields

```
<$vars search_text_pk="$:/state/popup/SearchAllFields">
<$list variable=show_code_pk filter="[<search_text_pk>addsuffix[-checkShowCode]]">
<$list variable=skip_system_pk filter="[<search_text_pk>addsuffix[-checkSkipSystem]]">
<$edit-text tiddler=<<search_text_pk>> field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler=<<skip_system_pk>>> Skip System </$checkbox><br>
<br>

<$list variable=cur_search_text filter="[<search_text_pk>get[text]addsuffix[(?i)]!match[]]">
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]else[no]]">
<$list variable=cur_skipsystem_text filter="[<skip_system_pk>get[text]else[yes]match[yes]count[]]">

<!--Card titles-->
<$list variable=cur_pk filter="[regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_skipsystem_text>] [<cur_pk>!is[system]count[]] +[sum[]match[1]]">

<$link to=<<cur_pk>> />: title
</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

<!--Card fields-->
<$list variable=cur_pk filter="[!regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_pk>is[system]count[]multiply<cur_skipsystem_text>match[0]]">
<$list variable=cur_field filter="[<cur_pk>fields[]]">
<$list variable=found_field filter="[<cur_pk>get<cur_field>regexp<cur_search_text>]">

<$link to=<<cur_pk>> />: <<cur_field>>
<$list variable=disp_code filter="[<cur_showcode_text>match[yes]]">
<$codeblock code=<<found_field>> />
</$list><!--disp_code-->
</$list><!--found_field-->
</$list><!--cur_field-->

</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

</$list><!--cur_skipsystem_text-->
</$list><!--cur_showcode_text-->
</$list><!--cur_search_text-->
</$list><!--skip_system_pk-->
</$list><!--show_code_pk-->
</$vars><!--search_text_pk-->

TiddlyWiki\Section Display

Card name = `mcr glbl_section_disp`

Tag = `$:/tags/Macro`

```
\define glbl_section_disp(ur_title, ur_section_num)
<$reveal type="nomatch" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="show">

!!$ur_title$ - Show
</$button></$reveal>
<$reveal type="match" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">

!!$ur_title$
</$button><br>

<<section$ur_section_num$>>

<$button style="float:right" class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">
---
</$button><br>
</$reveal>
\end
<!--|v
-- Card content call

\define section1()

section content

!!!here

\end
<<glbl_section_disp "Section 1" 1>>
^|-->

TiddlyWiki\Source Code Samples

!!TiddlyWiki Git repository sample code

[Home button]
<<ext "Tiddly Wiki Home Button source code">>

```
{{$:/core/images/home-button}}
```

<<<
{{$:/core/images/home-button}}
<<<


[Save button]
<<ext "TiddlyWiki Save Button source code">>

```
<$action-sendmessage $message="tm-save-wiki" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>
```

* This code says I can specify my own download file name

```
<span class="tc-dirty-indicator">
```

* This code changes the color of elements within the `<span>` to red when the Wiki file has not been saved

[TiddlyWiki TopBar Menu]

<<ext "TiddlyWiki TopBar Menu">>

```
<$button set="$:/state/sidebar" setTo="no"/>
<$button set="$:/state/sidebar" setTo="yes"/>
```

* These lines show that the `$:/state/sidebar` Card is "no" to hide the sidebar, or "yes" show it

TiddlyWiki\Split Lines into Storage

```
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>fields:exclude[created title modified]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<new_line_pk>> $field=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:25px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Temp Table

```
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>indexes[]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<ttbLINE>> $index=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:200px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$link to=<<ttbLINE>> />
<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Text Differences

```
<$diff-text source={{FirstTiddler}} dest={{SecondTiddler}}/>

TiddlyWiki\Textbox field

\define sample_data_e1()
<$edit-text tiddler="$:/state/popup/TestText1" field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
\end

\define sample_data_e2()
<$edit-text tiddler="$:/state/popup/TestText2" field=text default="here" placeholder="[no text yet]" autoHeight=yes tag=textarea/>
\end

You can choose to edit a Card or a Card's field in a single-line or multi-line textbox.

* The `default` parameter is automatically placed in the textbox when the Card does not exist
** Typing in the box will add to the default text
** The Card will be created when the text in the box is changed
** Otherwise the default text will not be saved

* The `placeholder` parameter is shown as greyed-out text when the Card does not exist and there is no default text, or the Card exists and the text field is empty
** Typing in the box will overwrite the placeholder text

Note: Editing a Card PK that starts with `$:/state/popup/` will not be saved and does not affect the Wiki's "dirty" flag

[[$:/state/popup/TestText1]]
<$codeblock code=<<sample_data_e1>> />
<<sample_data_e1>>

---
[[$:/state/popup/TestText2]]
<$codeblock code=<<sample_data_e2>> />
<<sample_data_e2>>

TiddlyWiki\TiddlySaver from Downloads

Make a small form with a timer that moves downloaded TiddlyWiki files back to their original folder

- I have not tried to play around with running TW5 on Node.js. I don't prefer having to use TiddlyDesktop as a separate web browser. Installing a plugin would only save my wiki changes under the downloads directory. I like using a portable web browser on my thumb drive, and I am able to run non-admin programs on my computer. So I made a small program with a timer to move each saved TW file from my Downloads directory back to its original loading location.

- I leave the program running all the time I am logged in. Alt-S saves the data in TiddlyWiki to the Downloads folder. After at most five seconds, the timer moves the file to overwrite the original location. The form flashes on the screen for one second and then hides itself until another move.

1) I created an alt-S shortcut macro to save the current wiki with a specific filename prefix (TWMove_), the entire file path - with substitutions for path-specific characters (: and \), and a time stamp. (Using split/join is accurate enough for me.)

Example: TWMove_C-colon-slash-RootDirOne-slash-SubDirTwo-slash-UrWiki.html

```

\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.html]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>
```

2) I have my web browser save all downloaded files to a specific Downloads folder. (Specifically on Google Chrome, I did install a plugin to automatically hide the dowloaded files bar. It was getting annoying.)

3) I created a small program with a multi-line textbox, and a timer to poll the Downloads folder every five seconds. It moves all the TWMove files in alphabetical order, so the latest timestamped file will be processed last. It finds the destination path as part of the filename. (Moving assumes the original TW.html file is not locked by the browser. This happened to me once, but I just had to restart the browser to release the file lock.)

The program's text box shows the folder I'm polling. When it picks up a file, the original path is pre-pended to the textbox's list of processed files and the form flashes in the foreground for a second. (I could have made a system tray pop-up notification instead.)

It's not perfect, but definitely doable for most amateur programmers.

TiddlyWiki\Transclude Card Field

```
<$transclude mode="block" tiddler=<<currentTiddler>> />

<$transclude mode="inline" tiddler=<<currentTiddler>> field="ref_data" />

TiddlyWiki\Unicode Character List

```
\define CharRef(ur_code, ur_line_grouping)
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]floor[]] " variable=div_val>
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]match<div_val>] "><br><sub>$ur_code$
<<glbl_dec_to_hex5 "$ur_code$">>
</sub><br>
</$list>
</$list>
[&#$ur_code$;]
\end

https://en.wikipedia.org/wiki/Unicode_block

https://en.wikipedia.org/wiki/Plane_(Unicode)


<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text=""/>
Line Grouping = 10
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text="16"/>
Line Grouping = 16
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text=""/>
Clear selection
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="0"/>
Show Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="65536"/>
Show Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="131072"/>
Show Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="196608"/>
Show Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)
</$button>

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

@@font-family: "Lucida Console", Courier, monospace;
<$list filter="[{$:/state/mcr CharRef LineGrouping}!match[]else[10]] " variable=line_grouping>
<$list filter="[[$:/state/mcr CharRef CharacterListBase]get[text]!match[]]">
<$list filter="[range[512]subtract[1]multiply[128]add{$:/state/mcr CharRef CharacterListBase}]" variable=cur_block>
<h2><<cur_block>></h2>
<$list filter="[range[128]subtract[1]] +[add<cur_block>] " variable=cur_code>
<$macrocall $name=CharRef ur_code=<<cur_code>> ur_line_grouping=<<line_grouping>> />
</$list>
</$list>
</$list>
</$list>


TiddlyWiki\Unicode Codepoints Used

```
\define dec_to_u_hex4()
<$list variable=cur_d4 filter="[[$(dec_num)$]divide[16]floor[]divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d4 filter="[[0]subtract<cur_d4>multiply[16]multiply[16]multiply[16]add[$(dec_num)$]]"
><$list variable=cur_d3 filter="[<rem_d4>divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d3 filter="[[0]subtract<cur_d3>multiply[16]multiply[16]add<rem_d4>]"
><$list variable=cur_d2 filter="[<rem_d3>divide[16]floor[]]"
><$list variable=rem_d2 filter="[[0]subtract<cur_d2>multiply[16]add<rem_d3>]"
><$list variable=hex filter="[[;]addsuffix<cur_d4>addsuffix[;]addsuffix<cur_d3>addsuffix[;]addsuffix<cur_d2>addsuffix[;]addsuffix<rem_d2>split[;10]join[A]split[;11]join[B]split[;12]join[C]split[;13]join[D]split[;14]join[E]split[;15]join[F]split[;]join[]]"
>\u<<hex>></$list><!--hex
--></$list><!--rem_d2
--></$list><!--cur_d2
--></$list><!--rem_d3
--></$list><!--cur_d3
--></$list><!--rem_d3
--></$list><!--cur_d4
-->
\end
\define entry_hexcode(ur_char, ur_code_page)
<$list variable=cur_codepage filter="""[[$ur_code_page$]!match[]else[0]multiply[256]]""">
<$list variable=dec_num filter="""[range[256]add<cur_codepage>]""">
<$wikify name=hex_unicode text=<<dec_to_u_hex4>> >
<$list filter="""[[$ur_char$]regexp<hex_unicode>]""" variable=match_text>
-$ur_char$-<<hex_unicode>>-&amp;#<<dec_num>>;
</$list><!--match_text-->
</$wikify><!--hex_unicode-->
</$list><!--cur_unicode-->
</$list><!--cur_unicode-->
\end
\define unicode_points(ur_pk)
<$list variable=code_page filter="[[$:/state/unicode_points_codepage]get[text]else[0]]">

Code page = <<code_page>> <$button

style="margin-left:30px">
<$list variable="next_page" filter="[<code_page>add[1]]"><$action-setfield $tiddler="$:/state/unicode_points_codepage" text=<<next_page>>/></$list>
Next page
</$button><$button

style="margin-left:30px">
<$action-setfield $tiddler="$:/state/unicode_points_codepage" text="0"/>
Reset
</$button><br>


<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]count[]!match[1]!match[0]]">-&#x005D;-\u005D-&amp;#93;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u0060]count[]!match[1]!match[0]]">-&#x0060;-\u0060-&amp;#96;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]join[]splitregexp[\u0060]join[]split[]each:value[]sort[]]">-<<cur_char>>-
<$macrocall $name=entry_hexcode ur_code_page=<<code_page>> ur_char=<<cur_char>> />
<br>
<br>
</$list><!--cur_char-->
</$list><!--code_page-->
\end

<<unicode_points "UrPK">>

TiddlyWiki\Upload File

!! Drag and drop
* Drag a file icon from the Windows Desktop or Windows Explorer over the Wiki until you see a top-margin green bar show
* Release the mouse to drop the file -> Opens card

!! Import Card
* Review the file list and uncheck and undesired import objects
* Click button Import -> Creates Cards

!! BrowseWidget

* Create a $browse tag -> Makes button
* Click button Choose File -> Opens dialog
* Choose a file -> Closes dialog, opens Card

!! Import Card
* Review the file list and uncheck and undesired import objects
* Click button Import -> Creates Cards

```
<$browse />
```

TiddlyWiki\Video and Audio

* Title = mcr glbl_ext_av
* Tag = `$:/tags/Macro`
* Note: The paths are relative to the current website. You cannot load Video or Audio content from other websites due to browser restrictions.

* Note: You can add attribute `poster="placeholder.png" ` to the Video tag if you have a specific image you want instead of the video's first frame

```
\define glbl_ext_video(UrFolder,UrVideo,UrTime)
<video width="320" height="180"
controls preload="metadata">
<source src="$UrFolder$/$UrVideo$.mp4#t=$UrTime$" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
\end
\define glbl_ext_audio(UrFolder,UrAudio,UrTime)
<audio controls preload="none">
<source src="$UrFolder$/$UrAudio$.mp3#t=$UrTime$" type=
"audio/mp3">
Your browser does not support the HTML 5 audio tag.
</audio>
\end

<!--|v
* Hard-coded to only use MP4 files

<<glbl_ext_video "MyVideosSubFolder" "MyVideoFile" "00:01:00">>

<<glbl_ext_video "file:///C:/UrFolder/UrSubFolder" "UrFilenameNoExtension" "00:01:00">>
^|-->
<!--|v
<<glbl_ext_audio "MyAudioSubFolder" "MyAudioFile" "00:01:00">>
^|-->

TiddlyWiki\View All Cards

```
<$list filter="[all[tiddlers]!tag[EXTLINK]!tag[IMG]!tag[INDEX]!tag[MCR]!tag[META]!has[draft.of]!is[image]!is[tag]!is[system]has[tags]!prefix[undefined]sort[title]]">
<hr>
<h2><$link to=<<currentTiddler>> /></h2>
{{||$:/core/ui/ViewTemplate/tags}}
<$transclude mode="block"/>
</$list>

TiddlyWiki\Wikify Text

```
<$wikify name=str_text_out text="&#65;">
A = <<str_text_out>>
</$wikify>

<$wikify name=str_text_out text="''bold font''" output=html>
B = <<str_text_out>>
</$wikify>

TiddlyWiki\WikiText Formatting

You can type most standard text without problems. Leading, repeated, or paired special characters may need escaped.

!Vertical Spacing

```
Pressing enter at the end of a line does not start a new paragraph.
Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph.
Press enter twice.
```

For example, see how the above two paragraphs are shown below:

Pressing enter at the end of a line does not start a new paragraph.
Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph.
Press enter twice.


!Leading Special Characters

!!Bulleted List Entry

```
*Bulleted List Entry
```

*Bulleted List Entry

Leading with an asterisk creates a bulleted list entry. To escape, prefix with four single-quotes.

If you want a single blank line between two bullet points, use a !''''! Heading Line without any title text.

```
''''*Bulleted List Entry
```

''''*Bulleted List Entry

!!Heading Line

```
!Heading Line
```

Starting a new paragraph line with an exclamation mark (!) results in a heading line.

```
!Heading Line
```

The above heading markup starts with an exclamation mark. To escape, prefix with four single-quotes.

```
''''!Heading Line
```

''''!Heading Line

!!Mono-spaced Text Block

```
 ```
 Mono-spaced Text Block
 ```
```

```
Mono-spaced Text Block
```

Leading with a triple back-tick creates a mono-space text block. To escape, surround the triple back-tick with doubled square-brackets.

```
[[''']] Regular typeface
```

[[```]] Regular typeface

!!Numbered List Entry

```
#Numbered List Entry
```

#Numbered List Entry

Leading with a pound-sign creates a numbered list entry. To escape, prefix with four single-quotes.

```
''''#Numbered List Entry
```

''''#Numbered List Entry

!!Quoted text block
```
<<<
Quoted text block
<<<
```

<<<
Quoted text block
<<<

Leading with a triple less-than creates a quoted text block. To escape, surround the 

```
''''<<< Unquoted text
```

''''<<< Unquoted text

!!URL Links

```
https://tiddlywiki.com/
```

https://tiddlywiki.com/

Start text with an "http'''':/''''/" "http'''':/''''/" will create a URL link. To escape, place four single-quotes before the colon and between the double forward-slashes.

```
https'''':/''''/tiddlywiki.com/
```

https'''':/''''/tiddlywiki.com/


!Repeated Special Characters

```
''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`
```

''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`

A number of repeated special characters are used as Wiki Markup to format text. To escape, place four single-quotes between the doubled characters or surround the doubled characters with doubled square-braces.

```
[['']]Bold Text[['']] /''''/Italic Text/''''/ ~''''~Strike-through Text~''''~ _''''_Underlined Text_''''_ ^''''^Raised-Small Text^''''^ ,'''',Lowered-Small Text,'''', [[`]]Mono-spaced Text[[`]]
```

[['']]Bold Text[['']] /''''/Italic Text/''''/ ~''''~Strike-through Text~''''~ _''''_Underlined Text_''''_ ^''''^Raised-Small Text^''''^ ,'''',Lowered-Small Text,'''', [[`]]Mono-spaced Text[[`]]

!Paired Special Characters

!!Literal Text

```
[[Literal Text]]
```

[[Literal Text]]

Surrounding text with doubled square-brackets shows the literal surrounded text without applying formatting. To escape, place four single-quotes between the first doubled square-brackets.

```
[''''[Literal Text]]
```

[''''[Literal Text]]

!!Transcluded Text

```
{{Other Tiddler Title}}

Note: The other tidder's content is "Other Tiddler Transcluded Text".
```

{{Other Tiddler Title}}

Surrounding text with doubled curly-braces shows the full content of another tiddler. To escape, place four single-quotes between the first doubled curly-braces.

```
{''''{Other Tiddler Title}}
```

{''''{Other Tiddler Title}}

!!HTML Markup

```
<b>HTML Markup</b>
```

<b>HTML Markup</b>

Surrounding text with angled-brackets uses HTML formatting. To escape, rename the first angle-bracket to &lt'''';

```
&lt;b>HTML Markup</b>
```

&lt;b>HTML Markup</b>

!!HTML Literals

```
&lt;

Note: &lt; represents a left angle-bracket, or the less-than symbol (<).
```

&lt;

Surrounding text with an ampersand (&) and a semi-colon translate to an HTML literal. To escape, place four single-quotes after the ampersand.

```
&lt;
```

&''''lt;


!!CSS Styles

You can apply CSS styles in-line with the text. Make sure you put the semi-colon at the end of the style list.

```
You can apply @@background-color:yellow; CSS styles @@ in-line with the text.
```

You can apply @@background-color:yellow; CSS styles @@ in-line with the text.


!!Tables

```
|!Cell1 |!Cell2 |
|Cell3 |Cell3 |

|^top left |^ top center |^ top right|
|middle left | middle center | middle right|
|,bottom left |, bottom center |, bottom right|


To merge a table cell with the one above, use the special cell text ~. To merge a cell with the one to its left use the text <. To merge one to its right use >. For example:

|Cell1 |Cell2 |Cell3 |Cell4 |
|Cell5 |Cell6 |Cell7 |<|
|Cell5 |~|Cell7 |Cell8 |
|>|Cell9 |Cell10 |Cell11 |

assigns the CSS classes "myclass" and "anotherClass" to the table
gives the table the caption "This is a caption"
adds a header row of cells with the text "Header"
adds a footer row of cells with the text "Footer"
|myclass anotherClass|k
|This is a caption |c
|Cell1 |Cell2 |
|Cell3 |Cell3 |
|Header|Header|h
|Footer|Footer|f
```

TiddlyWiki\Word Wrap

!! Hard-line breaks using CSS styles

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
.tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

* Note: When using this alternate CSS, wiki text markup will be ignored unless preceded by a double-spaced line
* Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

Sample Code:

```
*bullet 1
*bullet 2
*bullet 3
Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a ",,,,",,,," wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

*bullet 4 requires a preceding double-spaced line to be interpreted as wikitext
```

<<<
Results:

```
* bullet 1
* bullet 2
* bullet 3

Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a """ wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

* bullet 4 requires a preceding double-spaced line to be interpreted as wikitext
```
<<<

!! Apply stylesheet to cards with specific tag `linewrap`

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

!! Apply Styles to In-line Text

* Start a text block with @,,,,@ and the CSS styles with no spaces

Sample Code:

```
@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line
```

<<<
Result:

```
These are
separate lines
here

This is one big line
```
<<<

* or start in the middle of a text block

Sample Code:

```
This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.
```

<<<
Result:

```
This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.
```
<<<

TotalCommander

<<glbl_article_list>>

TotalCommander\Create new Text File

"""
[Total Commander directory]
- [Top of the directory]
- Hold down on the '..' button to see the menu -> Opens menu
- - or Hold down on any subdirectory name to see the menu -> Opens menu

- [context menu]
- Click option New Text file -> Opens dialog

- [Create new text file dialog]
- Enter a new text file name
- Click button OK -> Closes dialog

- [Directory list]
- Note: The new file was added to the current folder

TotalCommander\Local file desktop shortcut

"""
Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Total Commander directory]
- Hold down on file entry named like *.html -> Opens menu

- [context menu]
- Click option Create link on desktop -> Opens dialog

- [Create link dialog, main page, command line section]
- Click button '>>' -> Opens dialog

- [Choose app dialog, main page]
- Click option Choose app * -> Navigates page

- [Choose app dialog, Choose app * page]
- Click option Chrome -> Navigates page

- [Create link dialog, main page]
- Click button OK / Apply -> Closes dialog

[Android Desktop icons]
- Note: The icon was added to the desktop automatically

TW Project

<<glbl_article_list>>

TW Project\Check app

<<ext "Project Check app">>

Goal: Find food by aisle

TW Project\Code Snapshot

<<ext "TW Snapshot Review">>

Goal: Browse the code inside the WIki file

<<ext "TW Snapshot v5d01d23 main-site">>

<<ext "TW Snapshot v5d01d23 empty">>

<<ext "TW Snapshot v5d01d23 pre-release">>

<<ext "TW Snapshot v5d01d23 update">>

TW Project\Features list

<<ext "TW Features">>

Goal: Demonstrate every Wiki command and option

TW Project\Javascript Plugin instructions

<<ext "TW Create Javascript Plugin">>

TW Project\Shuffle List addon

<<ext "Shuffle List Entries">>

TW Project\Text Replace addon

<<ext "TW Addon Text Replace">>

Goal: Add text replacement functionality to the standard TWCard editor

TW Project\TiddlyWiki Manual

<<ext "TW Manual">>

Goal: Explain the Single-Page Quine Wiki architecture

TW Project\TW JS Pretty

<<ext "TW JS Pretty">>

Goal: Upload a text file and comment on each line, table or function

TW Project\Wiki Empty Setup

<<ext "Empty Wiki Setup">>

Goal: Use the empty TW document and generate a static HTML page

Unicode

<<glbl_article_list>>

Unicode\Code Blocks

<<ext "Unicode Block 00-Basic Latin">>

<<ext "Unicode Block 01-Latin Supplement">>

<<ext "Unicode Code Block List">>

<<ext "Unicode Block Planes">>

Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)

Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)

Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)

Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

Unicode\Latest Version

<<ext "Unicode Character Database">>

All files for the most up-to-date version of the Unicode Character Database can be found at: http://www.unicode.org/Public/UCD/latest/.

The latest text file databases are at https://www.unicode.org/Public/UCD/latest/ucd/. The latest set of text file databases is in a ZIP file at https://www.unicode.org/Public/UCD/latest/ucd/UCD.zip.

The list of Unicode Code Blocks are in the text database https://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt.

There is a list of names for the Unicode Code Points at https://www.unicode.org/Public/UCD/latest/ucd/Index.txt. There same list is sorted in Code Point order at https://www.unicode.org/Public/UCD/latest/ucd/NameAliases.txt. Each hex code can have multiple names.

The unique list of Unicode Code Points is at https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt. There is a character name and possibly an alternative name on each row.


VBNetCode

<<glbl_article_list>>

VBNetCode\Application Startup require DLLs

```
Option Strict On
Namespace My
    Partial Friend Class MyApplication
        Sub Main(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
            Mx.Want.TestReferencedAssemblies_errhnd(e)
            'Next goes to frmInput_1_Load, then Want.Compile_And_Run_Script
        End Sub
    End Class
End Namespace

Namespace Mx
    Partial Public Class Want
        Public Shared Sub TestReferencedAssemblies_errhnd(ur_startup_event_args As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs)
            Dim objERR_LIST = New ErrListBase : Try
                Call Assistant.TestReferencedAssemblies()

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                MsgBox(objERR_LIST.ToString, , My.Application.Info.Title)
                ur_startup_event_args.Cancel = True
            End If
        End Sub 'TestReferencedAssemblies_errhnd
    End Class 'Want
    
    Partial Public Class Assistant
        Public Shared Sub TestReferencedAssemblies()
            'Will error if DLL does is not available
            Dim objV1 = System.Data.SqlClient.SortOrder.Ascending
        End Sub 'TestReferencedAssemblies
    End Class 'Assistant
End Namespace 'Mx

VBNetCode\Checksum calculate

I want a .Net program to calculate the SHA512 hash of a file

```
Dim strHASH_KEY = ""
Using objSHA = New System.Security.Cryptography.SHA512Managed
    Using stmFILE = System.IO.File.OpenRead(flnDATA)
        strHASH_KEY = "[" & System.BitConverter.ToString(objSHA.ComputeHash(stmFILE)).Replace("-", "").ToLower & "]"
        'Convert.ToBase64String(
    End Using
End Using

VBNetCode\Copy File Lines

```
Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), bolAPPEND_FILE, gUTF8_FileEncoding)
	Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
		While stmDATA.EndOfStream = False
			'Character copy
			Dim intENTRY = stmDATA.Read()
			Dim strENTRY = ChrW(intENTRY)
			stmOUT_FILE.Write(strENTRY)
			
			'Line copy
			Dim strLINE = stmDATA.ReadLine()
			stmOUT_FILE.WriteLine(strLINE)
		End While 'stmDATA
	End Using 'stmDATA
End Using 'stmOUT_FILE
```

Split File into chunks of 100,000 lines each

```
Dim intFILE_COUNT = 0
Dim intLINE_COUNT = 0
Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
	While stmDATA.EndOfStream = False
		intFILE_COUNT += 1
		intLINE_COUNT = 0
		Dim strFILE_COUNT = intFILE_COUNT.ToString()
		If Len(strFILE_COUNT) = 2 Then
			strFILE_COUNT = "c" & strFILE_COUNT
		ElseIf Len(strFILE_COUNT) = 3 Then
			strFILE_COUNT = "d" & strFILE_COUNT
			
			End If 'strFILE_COUNT
		
		strFILE_COUNT = "e" & strFILE_COUNT
		Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT(strFILE_COUNT & ".TXT"), False, gUTF8_FileEncoding)
			While stmDATA.EndOfStream = False
				Dim strLINE = stmDATA.ReadLine()
				stmOUT_FILE.WriteLine(strLINE)
				intLINE_COUNT += 1
				
				If intLINE_COUNT >= 100000 Then
					Exit While
					
					End If
				
				End While 'stmDATA
			
			End Using 'stmOUT_FILE

		End While 'stmDATA
	
	End Using 'stmDATA

VBNetCode\DotNet Core Compile EXE

[https://github.com/dotnet/core/issues/5409]

<<<
In .NET 5 the single-file publish may produce more than one file and it's by design. See the expected behavior described here: 

https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md#user-experience

In 3.1 single-file is basically just a self-extracting executable - it writes everything into temp and runs from there. As such for the running app nothing really changes (everything is a file, with a path and so on).

In 5 we don't write to disk by default, all managed assemblies are loaded directly from the executable. The problem is native libraries - it's technically VERY difficult to include a random .dll in an executable and run it from the executable directly.

If you only take the .exe and run it, it won't work - it needs those additional files.

If you need .NET 5 but want the self-extracting behavior you can set IncludeAllContentForSelfExtract=true and it will behave basically the same as in 3.1.

There's also a "hybrid" mode IncludeNativeLibrariesForSelfExtract=true which will produce just one executable and that will write the native libraries to temp and then run.
<<<

User-replaced value = UrProjectDir

[UrProjectDir folder]
- Start with [[VBNetCode\DotNet Core New Project]]

"""
[Windows CLI]
- [Compile into an EXE]
- `dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep`
- Text output ->
"""

```
Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  t3 -> UrProjectDir\bin\Release\net5.0\win10-x64\UrProjectDir.dll
  t3 -> UrProjectDir\Dep\
```

"""
[UrProjectDir folder]
- [Look for the new folders]
- New sub-folders: bin, Dep
- Note: The compiled program is in the Dep subfolder named UrProjectDir.exe
- - The UrProjectDir.pdb file is used for debugging purposes and would not normally be deployed with your EXE file

[Windows CLI]
- [Remove the temporary folders in the UrProjectDir]
- `rd bin /s /q`
- `rd obj /s /q`
- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output shows as if you ran the command `dotnet run`

- Note: You can output the `System.AppContext.BaseDirectory` to find the Temp that holds the uncompressed program
"""

"""
[Program.vb file]
- [Replaces lines in Main sub]
- `Console.WriteLine(System.AppContext.BaseDirectory)`

[Windows CLI]
- [Compile into an EXE]
- `dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep`
- Note: If running DotNet Core 3.1,
- - `dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true -p:PublishSingleFile=true`
- -  The "--self-contained" option is incompatible with the "-p:PublishReadyToRun=true" and "-p:PublishSingleFile=true" options

- Note: When you choose the Portable publish option, you'll get a package that is capable of running on either x86 (32-bit) machines and x64 (64-bit) machines
- - The next run would have to JIT compile the application again as it is used
- - The advantage here is that you'd only need to distribute one package, and it'll run on both x86/x64 machines
- - `dotnet publish -c Release -r portable --self-contained`

- [Remove the temporary folders in the UrProjectDir]
- `rd bin /s /q`
- `rd obj /s /q`
- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output =
"""

```
C:\Users\UrUsername\AppData\Local\Temp\.net\UrProjectDir\SomeRandom-8-letters.SomeRandom-3-letters\
```

"""
- Note: This folder gets created on the first run the of UrProjectDir.exe
- - The second run starts faster because the files have already been extracted to this temporary folder
- - You can delete the temporary folder, and running the UrProjectDir.exe will create it again.

- Note: You can specify a different temporary folder by setting the Environment Variable `DOTNET_BUNDLE_EXTRACT_BASE_DIR`

- `SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%USERPROFILE%\Downloads\UrProjectDir\tmp`
- Note: You can set the Environment Variable in a batch file and it will not be saved for new Windows CLI windows.
- - To set it permanently, use `Control Panel` \ `System and Security` \ `System` \ `Advanced systems settings` \ `Advanced` tab \ `Environment Variables` button \ top or bottom section \ `New` button, Variable Name = `DOTNET_BUNDLE_EXTRACT_BASE_DIR`, Variable Value = `UrFullPathToTempDirectory`, `OK button`
- - Trying to use a relative directory path ends up not running the executable

- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output = 
"""

```
C:\Users\UrUsername\Downloads\UrProjectFolder\tmp\UrProjectFolder\SomeRandom-8-letters.SomeRandom-3-letters\
```

"""
- [Review the size of the TMP folder]
- `dir tmp /s`
- Text output = 23 Files, 8 Dirs

- [Remove the temporary directory]
- `rd tmp /s /q`

[UrProjectDir\Dep folder]
- [Create a script to run the project and clean up the temporary files]
- New file = UrProjectDir.cmd

[UrProjectDir.cmd file]
"""

```
@@ECHO OFF
SET CUR_DIR=%~dp0
SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%CUR_DIR%tmp
"%CUR_DIR%UrProjectDir.exe"
rd "%CUR_DIR%bin" /s /q 2> nul
rd "%CUR_DIR%obj" /s /q 2> nul
rd "%CUR_DIR%tmp" /s /q 2> nul
```

"""
[Windows CLI]
- [Run the clean-execution script]
- `Dep\UrProjectDir.cmd`
- Note: There is no tmp subfolder

VBNetCode\DotNet Core Installation using Binaries

"""
[https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net50]
"""

<<<
As an alternative to the Windows installers for .NET, you can download and manually install the SDK or runtime. Manual install is usually performed as part of continuous integration testing. For a developer or user, it's generally better to use an installer.

Both .NET SDK and .NET Runtime can be manually installed after they've been downloaded. If you install .NET SDK, you don't need to install the corresponding runtime. First, download a binary release for either the SDK or the runtime from one of the following sites:

https://dotnet.microsoft.com/download/dotnet/5.0

https://dotnet.microsoft.com/download/dotnet-core

Create a directory to extract .NET to, for example %USERPROFILE%\dotnet. Then, extract the downloaded zip file into that directory.

By default, .NET CLI commands and apps won't use .NET installed in this way and you must explicitly choose to use it. To do so, change the environment variables with which an application is started:

```
set DOTNET_ROOT=%USERPROFILE%\dotnet
set PATH=%USERPROFILE%\dotnet;%PATH%
set DOTNET_MULTILEVEL_LOOKUP=0
```

This approach lets you install multiple versions into separate locations, then explicitly choose which install location an application should use by running the application with environment variables pointing at that location.

When DOTNET_MULTILEVEL_LOOKUP is set to 0, .NET ignores any globally installed .NET version. Remove that environment setting to let .NET consider the default global install location when selecting the best framework for running the application. The default is typically C:\Program Files\dotnet, which is where the installers install .NET.
<<<

"""
[https://docs.microsoft.com/en-us/dotnet/core/install/how-to-detect-installed-versions?pivots=os-windows]
"""

<<<
When you install .NET from an installer or script, it's installed to a standard folder. Much of the time the installer or script you're using to install .NET gives you an option to install to a different folder. If you choose to install to a different folder, adjust the start of the folder path.

dotnet executable in C:\program files\dotnet\dotnet.exe

.NET SDK in C:\program files\dotnet\sdk\{version}\

.NET Runtime in C:\program files\dotnet\shared\{runtime-type}\{version}\
<<<

VBNetCode\DotNet Core Installed Path

"""
[Windows CLI]
- [Run the system information report]
- `dotnet --info`
"""

```
.NET Core SDK (reflecting any global.json):
 Version:   3.1.401
 Commit:    5b6f5e5005

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18363
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.401\

Host (useful for support):
  Version: 3.1.7
  Commit:  fcfdef8d6b

.NET Core SDKs installed:
  3.1.301 [C:\Program Files\dotnet\sdk]
  3.1.401 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
```

VBNetCode\DotNet Core New Project

[https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new]

<<<
You can run dotnet new --list or dotnet new -l to see a list of all installed templates. If the TEMPLATE value isn't an exact match on text in the Templates or Short Name column from the returned table, a substring match is performed on those two columns.

Starting with .NET Core 3.0 SDK, the CLI searches for templates in NuGet.org when you invoke the dotnet new command in the following conditions:

* If the CLI can't find a template match when invoking dotnet new, not even partial.
* If there's a newer version of the template available. In this case, the project or artifact is created but the CLI warns you about an updated version of the template.
<<<

[https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli]

"""
User-replaced value = UrProjectDir

[Windows CLI]
- [Navigate to the User Downloads folder]
- `cd %USERPROFILE%\Downloads`
- [Create a new DotNet Core project named UrProjectDir]
- `dotnet new console -lang VB -o UrProjectDir`
- Text output =
"""

```
Getting ready...
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj...
  Determining projects to restore...
  Restored C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj (in 65 ms).
Restore succeeded.
```

"""
- [Navigate to the new UrProjectDir]
- `cd UrProjectDir`

[UrProjectDir folder]
- [Look for the new files and folders]
- New files: UrProjectDir.vbproj and Program.vb
- New sub-folder: obj

[Windows CLI]
- [Download a dependency]
- `dotnet add package Figgle`
- Text output =
"""

```
  Determining projects to restore...
  Writing C:\Users\Dad\AppData\Local\Temp\tmpE018.tmp
info : Adding PackageReference for package 'Figgle' into project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info :   GET https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json
info :   OK https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json 104ms
info : Restoring packages for C:\Users\Dad\Downloads\t3\t3.vbproj...

info : Installing runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple 4.3.0.
info : Installing runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl 4.3.0.

info : Package 'Figgle' is compatible with all the specified frameworks in project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : PackageReference for package 'Figgle' version '0.4.0' added to file 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : Committing restore...
info : Writing assets file to disk. Path: C:\Users\Dad\Downloads\t3\obj\project.assets.json
log  : Restored C:\Users\Dad\Downloads\t3\t3.vbproj (in 8.04 sec).
```

"""
[Program.vb file]
- [Replace lines in Main sub]
- `Console.WriteLine(Figgle.FiggleFonts.Standard.Render("Hello, World!"))`

[Windows CLI]
- [Compile into an EXE and run it]
- `dotnet run`
- If you did not enter the program line incorrectly, Text output =
"""

```
Program.vb(5,79): error BC30037: Character is not valid.

The build failed. Fix the build errors and run again.
```

"""
- If you entered the program line correctly, Text output shows Hello World in a large font
"""

VBNetCode\DotNetCore Installation using Installer

"""
[https://dotnet.microsoft.com/platform/support/policy/dotnet-core]
- 2020m11d24: .NET 5 is the current version of DotNet Core. It was released on November 10, 2020.

[https://dotnet.microsoft.com/download/dotnet-core]
- [Supported versions, record Version = .NET 5.0]
- Click link .NET 5.0 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/5.0]
- [record Release Information = v5.0.0, Build Apps column]
- [SDK grid, record OS = Windows]
- Click link x86 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-windows-x64-installer]
- Auto-download started -> Saves file

[Local Computer Downloads folder]
- [filename = dotnet-sdk-5.0.100-win-x64.exe]
- Run program -> Opens form

[Microsoft .NET SDK 5.0.100 (x64) Installer window]
- Click button Install -> Windows dialog
- Question: Do you want to allow the program to make changes to your computer?
- Click button Yes -> Closes dialog
- Wait for progress bar to complete -> Navigates page
- Note: Installation was successful
- Click button Close -> Closes window

[[VBNetCode\DotNet Core Installed Path]]

VBNetCode\File Exists

```
Dim bolFILE_EXISTS = System.IO.File.Exists(flnDATA)

VBNetCode\File Size

```
Dim sioFILE = New System.IO.FileInfo(flnDATA)
Dim intFILE_SIZE = sioFILE.Length

VBNetCode\Global functions passed as Classes

```
    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

VBNetCode\In-Memory Compile

```
Namespace Mx
    Public Class ScriptRun
        ' Build a Hello World program graph using 
        ' System.CodeDom types.
        Public Class enmC_V_J
            Inherits bitBASE
            Public Shared CSharp As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared VisualBasic As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared JScript As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
        End Class 'enmC_V_J

        Public Shared Function RunCode(ur_provider As Mx.ScriptRun.enmC_V_J, ur_input_script As String, ur_assembly_folder As String) As String
            Dim strSOURCE_CODE = ur_input_script
            Dim stpERR_MSG = Strapd()
            Dim stpCODE_FILE = Strapd()
            ' Configure a CompilerParameters that links System.dll and produces the specified executable file.
            Dim objAPP_DOMAIN As AppDomain = Nothing
            Dim objCOMPILE_RUNNER As CompilerRunner = Nothing
            Dim objCOMPILER_PARM = New System.CodeDom.Compiler.CompilerParameters
            Dim objCOPMILER_RESULT As System.CodeDom.Compiler.CompilerResults = Nothing
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing

            If stpERR_MSG.Length = 0 Then
                'objAPP_DOMAIN = System.AppDomain.CreateDomain("MyDomain", AppDomain.CurrentDomain.Evidence, CreateSetup())
                'objCOMPILE_RUNNER = objAPP_DOMAIN.CreateInstanceFromAndUnwrap(GetType(CompilerRunner).Assembly.Location, GetType(CompilerRunner).FullName)
                objCOMPILE_RUNNER = New Mx.CompilerRunner
                stpERR_MSG.d(objCOMPILE_RUNNER.Compile(stpCODE_FILE.ToString, ur_provider.name, objCOMPILER_PARM))
            End If

            If stpERR_MSG.Length = 0 Then
                stpERR_MSG.d(objCOMPILE_RUNNER.Run("Mx.Class1", "RetVal"))
            End If

            If objAPP_DOMAIN IsNot Nothing Then
                'AppDomain.Unload(objAPP_DOMAIN)
            End If
            ' Return the results of compilation.
            Return stpERR_MSG.ToString
        End Function 'RunCode

        Public Shared Function CreateSetup() As AppDomainSetup
            Dim retSETUP = New AppDomainSetup
            With retSETUP
                .ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
                .ApplicationName = "TestDLL"
                .DisallowBindingRedirects = False
                .ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
                .LoaderOptimization = LoaderOptimization.MultiDomainHost
            End With
            CreateSetup = retSETUP
        End Function 'CreateSetup
    End Class 'ScriptRun

    Public Class CompilerRunner
        Inherits MarshalByRefObject

        Public cur_assembly As System.Reflection.Assembly = Nothing
        'AppDomain.CurrentDomain.FriendlyName = MyDomain

        Public Function Compile(ur_code As String, ur_provider As String, ur_compiler_parm As System.CodeDom.Compiler.CompilerParameters) As String
            Dim stpERR_MSG = Strapd()
            Me.cur_assembly = Nothing
            Dim provider As System.CodeDom.Compiler.CodeDomProvider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider(ur_provider) 'New Microsoft.VisualBasic.VBCodeProvider 
            Dim objCOMPILER_RESULT = provider.CompileAssemblyFromSource(ur_compiler_parm, ur_code) ' Strapd().d("Namespace Mx").dLine("Public Class Class1").dLine("Public Shared Function RetVal() As String").dLine("RetVal=""Hi""").dLine("End Function").dLine("End Class").dLine("End Namespace"))
            If objCOMPILER_RESULT.Errors.Count = 0 Then
                Me.cur_assembly = objCOMPILER_RESULT.CompiledAssembly

            Else
                stpERR_MSG.dLine("Compile Errors")
                stpERR_MSG.dLine()
                For Each errItem As System.CodeDom.Compiler.CompilerError In objCOMPILER_RESULT.Errors
                    stpERR_MSG.dLine(errItem.ErrorText & " [" & errItem.Line + 5 & "]")
                    stpERR_MSG.dLine()
                    stpERR_MSG.dLine()
                Next errItem

                stpERR_MSG.dLine(ur_code)
            End If 'objCOMPILER_RESULT

            Compile = stpERR_MSG.ToString
        End Function 'Comiple

        Public Function Run(ur_type_name As String, ur_method_name As String) As String
            Dim stpERR_MSG = Strapd()
            Dim t As System.Type = Me.cur_assembly.CreateInstance(ur_type_name).GetType()
            'Dim objRESULT = t.InvokeMember(ur_method_name, System.Reflection.BindingFlags.InvokeMethod, Nothing, Me.cur_assembly, {})
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing
            For Each m As System.Reflection.MethodInfo In t.GetMethods
                If m.Name = ur_method_name Then
                    objMETHOD_MAIN = m
                    Exit For
                End If
            Next m

            If objMETHOD_MAIN IsNot Nothing Then
                Dim objRESULT = objMETHOD_MAIN.Invoke(Nothing, Nothing)
                If objRESULT IsNot Nothing Then
                    stpERR_MSG.dLine(objRESULT.ToString)
                End If 'objRESULT
            End If 'objMETHOD_MAIN

            Run = stpERR_MSG.ToString
        End Function 'Run
    End Class 'CompileRunner
End Namespace 'Mx

VBNetCode\Send Keys

Send one alt-tab

```
System.Windows.Forms.SendKeys.Send("%{TAB}")
```

Hold down Alt, press alt-tab twice, and release Alt

```
System.Windows.Forms.SendKeys.Send("%({TAB}{TAB})")
```

The Windows key is not so easy to emulate.
- Auto-It or Auto-Hotkey can do more complicated patterns
- VB.Net can use PInvoke to have more capabilities

VBNetCode\Text file to JSON Lines

This outputs a file that can be dragged into TiddlyWiki.

```
<$list variable=cur_char filter="[[UrPK]get[text]splitregexp[\n]join[]split[]each:value[]!match[ ]sort[]]">
<<cur_char>>:
<$list variable=disp_name filter="[[Unicode Char Names]getindex<cur_char>else[missing]]">
<<disp_name>>
</$list><!--disp_name-->
<br>
</$list><!--cur_char-->

[[Unicode Char Names]]
```


```
Dim strFILE_PATH = "UnicodeData.txt"
Dim strOUT_PATH = strFILE_PATH & ".json"
Using stmOUT_FILE = New System.IO.StreamWriter(strOUT_PATH)
	Dim qs = """"
	Dim strESC_DQT = "\" & qs
	stmOUT_FILE.Write("[{""created"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & ",""modified"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & "," &
		qs & "title" & qs & ":" & qs & "Unicode Char Names" & qs & ",""type"":""application/json"",""text"":""{")
	Using stmDATA = New System.IO.StreamReader(strFILE_PATH)
		Dim LINCTR = 0
		While stmDATA.EndOfStream = False
			Dim strLINE = stmDATA.ReadLine()
			Dim intFOUND_SPRTR = InStr(strLINE, ";")
			
			Dim strHEX = Mid(strLINE, 1, intFOUND_SPRTR - 1)
			Dim intCHAR = Cint("&H" & strHEX)
			Dim strCHAR = UCase(strHEX)
			Dim strPREFIX = Left(strCHAR, 2)
			If Len(strCHAR) <> 4 Then
				strPREFIX = ""
			End If
			
			If intCHAR < 32 Then
			  strCHAR = ""
			ElseIf intCHAR > 65534 OrElse
			  strPREFIX = "D8" OrElse
			  strPREFIX = "D9" OrElse
			  strPREFIX = "DA" OrElse
			  strPREFIX = "DB" OrElse
			  strPREFIX = "DC" OrElse
			  strPREFIX = "DD" OrElse
			  strPREFIX = "DE" OrElse
			  strPREFIX = "DF" Then
				strCHAR = "\u" & strHEX
			Else
				strCHAR = CHRW(intCHAR)
				If strCHAR = "\" Then
					strCHAR = "\\\\"
				ElseIf strCHAR = """" Then
					strCHAR = "\\\" & """"
				End If
			End If

			If strCHAR <> "" Then
				LINCTR += 1
				If LINCTR > 1 Then
					stmOUT_FILE.Write(",")
				End If
				stmOUT_FILE.Write("\n    " & strESC_DQT & strCHAR & strESC_DQT & ":" & " " & strESC_DQT & strLINE.Replace("\", "\\").Replace(Chr(10), "\n").Replace(qs, strESC_DQT).Replace("<", "&lt;") & strESC_DQT)
			End If
		End While 'stmDATA
	End Using 'stmDATA
	
	stmOUT_FILE.Write("\n}" & qs & "}]")
End Using 'stmOUT_FILE

VBNetCode\To Hex

"""
Change string with numbers (0 to 9) and/or letters (a-f) into decimal number

[q/a page]
- https://stackoverflow.com/questions/642417/how-do-you-convert-hex-to-decimal-using-vb-net

[sample code]
"""

```
Dim strTEXT = "FF"
Dim strHEX_CODE = "&H" & strTEXT
Dim intNUMBER = CInt(strHEX_CODE)
MsgBox(intNUMBER) -> 255

VBNetCode\Unicode Code Point

<<ext "Microsoft DotNet Char ConvertToUTF32">>

* Note: The index can be any character in the string

```
retval = char.ConvertToUtf32(s:="A", index:=0).Tostring
```

<<<
Result:

```
65
```
<<<

VBNetCode\UserBowl example

```
    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As zapp_folder = TRow(Of enmUN).glbl.Trbase(Of zapp_folder).NewBitBase() : Public Class zapp_folder : Inherits enmUN : End Class
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared background_color As zbackground_color = TRow(Of enmUN).glbl.Trbase(Of zbackground_color).NewBitBase() : Public Class zbackground_color : Inherits enmUN : End Class
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_project_code As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared compiler_exe As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared form_title As zform_title = TRow(Of enmUN).glbl.Trbase(Of zform_title).NewBitBase() : Public Class zform_title : Inherits enmUN : End Class
        Public Shared path As zpath = TRow(Of enmUN).glbl.Trbase(Of zpath).NewBitBase() : Public Class zpath : Inherits enmUN : End Class
        Public Shared script_path As zscript_path = TRow(Of enmUN).glbl.Trbase(Of zscript_path).NewBitBase() : Public Class zscript_path : Inherits enmUN : End Class
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared window_status As zwindow_status = TRow(Of enmUN).glbl.Trbase(Of zwindow_status).NewBitBase() : Public Class zwindow_status : Inherits enmUN : End Class
    End Class

    Public Class enmUR_Color
        Inherits bitBASE
        Public Shared Clear As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Green As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Red As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
    End Class

    Public Class enmUR_Status
        Inherits bitBASE
        Public Shared Show As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
        Public Shared Close As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'db.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit(Have.WindowsMsgBox, Have.WindowsCboard)
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)
            Private enrBackground_Color As System.Drawing.Color
            Private enrUR_Color As enmUR_Color

            Public ReadOnly Property Background_Color_of_Form As System.Drawing.Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color_of_Form = Me.enrBackground_Color
                End Get
            End Property 'Background_Color_of_Form

            Public Property Background_Color As enmUR_Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color = Me.enrUR_Color
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As enmUR_Color)
                    Dim intCOLOR = System.Drawing.Color.Transparent
                    If value Is enmUR_Color.Red Then
                        intCOLOR = System.Drawing.Color.Red

                    ElseIf value Is enmUR_Color.Green Then
                        intCOLOR = System.Drawing.Color.Green
                    End If

                    Me.enrBackground_Color = intCOLOR
                    Me.enrUR_Color = value
                    Me.v(enmUB.contents) = value.name
                End Set
            End Property 'Contents

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_bowlname_is(ur_cmp As enmUN) As Boolean
                v_bowlname_is = AreEqual(Me.v(enmUB.bowl_name), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_cmp As enmUR_Color) As Boolean
                v_is = AreEqual(Me.Contents, ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit(ur_windowsmsgbox_env As Have.glblWindowsMsgBox, ur_windowscboard_env As Have.glblWindowsCboard)
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = ur_windowsmsgbox_env.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        ur_windowscboard_env.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Dim strASSEMBLY_EXE = mt
                Try
                    strASSEMBLY_EXE = My.Application.Info.Title
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_FOLDER = FileNamed()
                Try
                    flnASSEMBLY_FOLDER.wAssemblyDir(My.Application.Info)
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_PATH = flnASSEMBLY_FOLDER.gCopy.d(strASSEMBLY_EXE)
                Me.SelKey(enmUN.app_name).Contents = flnASSEMBLY_PATH.FileGroup
                Me.SelKey(enmUN.app_path).Contents = flnASSEMBLY_PATH
                Me.SelKey(enmUN.app_folder).Contents = flnASSEMBLY_FOLDER

                'enmUN.compiler_exe, enmUN.path take the first non-prefixed parameters; they are just file paths but without /parameter_name=
                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText, enmUN.compiler_exe, enmUN.path)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function 'InsFrom_Application

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCboard(ur_hdr As Boolean) As Integer
                ToCboard = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN

VBNetCode\Version

<<ext "WestWindCom Net Core Runtime">>
<<ext "SO.com RunTime Net 4.5">>

```
Function version_info() As String
version_info = "flag CLR 4.5 Features = " & If(Type.GetType(typeName:="System.Reflection.ReflectionContext", throwOnError:=False) Is Nothing, "", "True") & vbCrLf
version_info &= "flag CLR 4.51 Features = " & If(Type.GetType(typeName:="System.Runtime.GCLargeObjectHeapCompactionMode", throwOnError:=False) Is Nothing, "", "True") & vbCrLf
version_info &= "CLR Version = " & System.Environment.Version.ToString & vbCrLf
version_info &= "CLR Local Path = " & System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() & vbCrLf
version_info &= "Operating System = " & CType(System.Attribute.GetCustomAttribute(System.Reflection.Assembly.GetEntryAssembly(), GetType(System.Runtime.Versioning.TargetFrameworkAttribute)), System.Runtime.Versioning.TargetFrameworkAttribute).FrameworkName & " on " & System.Runtime.InteropServices.RuntimeInformation.OSDescription
End Function
```

VBNetProject

<<glbl_article_list>>

VBNetProject\~Clear Local

```
rd /s /q bin
rd /s /q obj
pause

VBNetProject\~Rebiuld Local

```
for %%f in (*.sln) do (
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
	
    for /D %%m in ("C:\Program Files (x86)\MSBuild\*\Bin\MSBuild.exe") do (
        "%%~m" /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
   )
:compile_complete
pause
del ..\Dep\*.exe
move bin\Release\*.exe ..\Dep
rd /s /q bin
rd /s /q obj
pause

VBNetProject\dbUserInputMock

!! Automatically convert the form to the dbUserInput class

```
Partial Public Class frmInput_1
    <System.Diagnostics.DebuggerHidden()>
    Public Shared Widening Operator CType(b As frmInput_1) As Mx.dbUserInput
        Return New Mx.dbUserInput(b, b.txtNotice_Message)
    End Operator
End Class 'frmInput_1
```

!! Setup the mock classes
* Create flat classes that have the desired values

```
Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock
End Namespace 'Mx2
```

* In a copy of the Mx.dbUserInput class, rename every `System.Windows.Forms` reference to `Mx2.Mock`

```
Option Strict On
Namespace Mx
    Public Class componentTextBox
        Private objTEXT_BOX As System.Windows.Forms.TextBox

        Public Sub New(ur_textbox As System.Windows.Forms.TextBox)
            objTEXT_BOX = ur_textbox
        End Sub

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objTEXT_BOX IsNot Nothing Then
                    Text = objTEXT_BOX.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objTEXT_BOX IsNot Nothing Then
                    objTEXT_BOX.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'componentTextBox

    Public Class dbUserInput
        Private objINPUT_FORM As System.Windows.Forms.Form
        Public txtNotice_Message As componentTextBox

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_input_form As System.Windows.Forms.Form, ur_notice_message_textbox As System.Windows.Forms.TextBox)
            objINPUT_FORM = ur_input_form
            Me.txtNotice_Message = New componentTextBox(ur_notice_message_textbox)
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Close()
            If objINPUT_FORM IsNot Nothing Then
                objINPUT_FORM.Close()
            End If
        End Sub

        Public Property BackColor As System.Drawing.Color
            <System.Diagnostics.DebuggerHidden()>
            Get
                BackColor = Nothing
                If objINPUT_FORM IsNot Nothing Then
                    BackColor = objINPUT_FORM.BackColor
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As System.Drawing.Color)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.BackColor = value
                End If
            End Set
        End Property 'BackColor

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objINPUT_FORM IsNot Nothing Then
                    Text = objINPUT_FORM.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'dbUserInput
End Namespace 'Mx
```

!! Create sample data
* Load the mock dbUserInput with the testing state

```
Dim mockTextBox = New Mock.TextBox
Dim mockForm = New Mock.Form
Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
Call Mx.UserAction.Run_Script_errhnd(mockUserInput)
```

* Compare the mock dbUserInput field changes to the expected result state

```
Dim strFOUND_RESULT = mockTextBox.Text
If strFOUND_RESULT = strEXPECTED_RESULT Then
	intPASS_COUNT += 1

Else
	intFAIL_COUNT += 1
	stpMOCK_REPORT.dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`").dLine())
End If 'strFOUND_RESULT
```

VBNetProject\DeveloperSettings

<<ext "DeveloperSettings HTM"">>

<<ext "DeveloperSettings ZIP"">>

VBNetProject\MxBaseEc13

<<ext "MxBase Classes">>

```
Option Strict On
Namespace Mx '2020m01d03
    Public Module ConstVar
        Public Const mt = ""
        Public Const qs = """"
        Public Const qt = "'"
        Public Const s = " "

        <System.Diagnostics.DebuggerHidden()>
        Public Function AreEqual(ur_val As String, ur_cmp As String) As Boolean
            AreEqual = String.Equals(ur_val, ur_cmp, System.StringComparison.CurrentCultureIgnoreCase)
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b0(ur_val As Integer) As Integer
            b0 = ur_val - 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b1(ur_val As Integer) As Integer
            b1 = ur_val + 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function ContainingText(ur_large_text As String, ur_small_text As String) As Boolean
            ContainingText = InStr(ur_large_text, ur_small_text, CompareMethod.Text) > 0
        End Function 'ContainingText
        <System.Diagnostics.DebuggerHidden()>
        Public Function gUTF8_FileEncoding() As System.Text.UTF8Encoding
            gUTF8_FileEncoding = glbl.gUTF8_Encoding
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function EndingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            EndingWithText = AreEqual(Right(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'EndingWithText
        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText(ur_value As String) As Boolean
            HasText = Not String.IsNullOrWhiteSpace(ur_value)
        End Function 'HasText
        <System.Diagnostics.DebuggerHidden()>
        Public Function StartingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            StartingWithText = AreEqual(Left(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'StartingWithText

        <System.Diagnostics.DebuggerHidden()>
        Public Function CmdOutput(ur_exec_path As String, Optional ur_exec_param As String = mt) As String
            Dim objPCS As New System.Diagnostics.Process()
            With 1 : Dim prcINFO = objPCS.StartInfo
                prcINFO.FileName = ur_exec_path
                prcINFO.Arguments = ur_exec_param
                prcINFO.UseShellExecute = False
                prcINFO.RedirectStandardOutput = True
                prcINFO.CreateNoWindow = True
            End With 'prcINFO

            objPCS.Start()
            CmdOutput = objPCS.StandardOutput.ReadToEnd()
            objPCS.WaitForExit()
        End Function 'CmdOutput

        <System.Diagnostics.DebuggerHidden()>
        Public Function FileNamed() As MxText.FileName
            FileNamed = New MxText.FileName
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Strapd() As Strap
            Strapd = New Strap
        End Function

        Public Class glbl
            Private Shared objUTF8_ENCODING As System.Text.UTF8Encoding

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If objUTF8_ENCODING Is Nothing Then
                    objUTF8_ENCODING = New System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier:=False, throwOnInvalidBytes:=True)
                End If
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function gUTF8_Encoding() As System.Text.UTF8Encoding
                Call glbl.Init()
                gUTF8_Encoding = glbl.objUTF8_ENCODING
            End Function
        End Class 'glbl
    End Module 'ConstVar

    Public Class ErrListBase
        Dim pstpNOTICE_MSG As Strap

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            pstpNOTICE_MSG = Strapd()
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Function DoContinue() As Boolean
            DoContinue = (Me.Found = False)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            If pstpNOTICE_MSG.Length > 0 Then
                pstpNOTICE_MSG.dLine().dLine()
            End If

            pstpNOTICE_MSG.dLine(ur_exception.Message)
            pstpNOTICE_MSG.dLine(Strapd().d("Error in @r1.@r2").r1(ur_methodbase.DeclaringType.Name).r2(ur_methodbase.Name).dS("(status: @r1)").r1(ur_procedure_status))
        End Sub 'dError_Data

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Stack(ur_exception As System.Exception)
            Dim hr As Integer = System.Runtime.InteropServices.Marshal.GetHRForException(ur_exception)
            pstpNOTICE_MSG.dLine(ur_exception.GetType.ToString & "(0x" & hr.ToString("X8") & "): " & ur_exception.Message & System.Environment.NewLine & ur_exception.StackTrace & System.Environment.NewLine)
            Dim st = New System.Diagnostics.StackTrace(ur_exception, True)
            For Each objFRAME In st.GetFrames
                If objFRAME.GetFileLineNumber() > 0 Then
                    pstpNOTICE_MSG.dLine("Line:" & objFRAME.GetFileLineNumber() & " Filename: " & System.IO.Path.GetFileName(objFRAME.GetFileName) & System.Environment.NewLine)
                End If
            Next objFRAME
        End Sub 'dError_Stack

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function Found() As Boolean
            Found = (pstpNOTICE_MSG.Length > 0)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = pstpNOTICE_MSG
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Throw_Error_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            Call Me.dError_Data(ur_exception, ur_methodbase, ur_procedure_status)
            Throw New LocalException(mt)
        End Sub 'Throw_Error_Data


        Public Class LocalException
            Inherits System.Exception

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String)
                MyBase.New(message)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String, inner As System.Exception)
                MyBase.New(message, inner)
            End Sub
        End Class 'LocalException
    End Class 'ErrListBase

    Public Class iWrap(Of T)
        Public v As T

        Public Sub New(ur_t As T)
            Me.v = ur_t
        End Sub
    End Class 'iWrap

    Public Class ObaCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Obalist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list As Obalist(Of T) = Nothing)
            Call MyBase.New(prv.TotalItems(ur_list))
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObaCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property v() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObaCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function TotalItems(Optional ur_list As Obalist(Of T) = Nothing) As Integer
                TotalItems = 0
                If ur_list IsNot Nothing Then
                    TotalItems = ur_list.Count
                End If
            End Function 'TotalItems
        End Class 'prv
    End Class 'ObaCTR

    Public Class ObjCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Objlist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_list As Objlist(Of T))
            Call MyBase.New(ur_list.Count)
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObjCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property row() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                row = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObjCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function
    End Class 'ObjCTR

    Public Class Obalist(Of T)
        Private vobjLIST() As T

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list() As T = Nothing)
            Me.vobjLIST = ur_list
        End Sub

        Public ReadOnly Property Count() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Count = Me.vobjLIST.Length
            End Get
        End Property

        Public Property Item(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                Item = Me.vobjLIST(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.vobjLIST(ur_index) = ur_val
            End Set
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function kvp() As ObaCTR(Of T)
            kvp = New ObaCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Obalist

    Public Class Objlist(Of T)
        Inherits System.Collections.Generic.List(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As ObjCTR(Of T)
            kvp = New ObjCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Objlist

    Public Class SDPCTR(Of T As {New})
        Inherits RCTR

        Private vsdpLIST As SdPair(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdplist As SdPair(Of T))
            Call MyBase.New(ur_sdplist.Count)
            Me.vsdpLIST = ur_sdplist
        End Sub

        Public Shadows ReadOnly Property Current() As SDPCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDPCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property l() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = Me.vsdpLIST.l_enm(Me.Indexenm)
            End Get
        End Property

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdpLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDPCTR

    Public Class SdPair(Of T As {New})
        Inherits Sdata
        Private vobjT As System.Collections.Generic.Dictionary(Of String, T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            vobjT = New System.Collections.Generic.Dictionary(Of String, T)
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function d(ur_val As String, ur_link As T) As SdPair(Of T)
            d = Me
            Call Me.Add(ur_val)
            Call vobjT.Add(ur_val, ur_link)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDPCTR(Of T)
            kvp = New SDPCTR(Of T)(Me)
        End Function

        Public Property l(ur_key As String) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = vobjT.Item(ur_key)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(ur_key) = ur_val
            End Set
        End Property

        Public Property l_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_b1 = vobjT.Item(Me.v_b1(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_b1(ur_index)) = ur_val
            End Set
        End Property

        Public Property l_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_enm = vobjT.Item(Me.v_enm(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_enm(ur_index)) = ur_val
            End Set
        End Property
    End Class 'SdPair

    Public Class RCTR
        Private pintMAX_NUM As Integer
        Private pintCUR_NUM As Integer

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(ByVal b As RCTR) As Integer
            Return b.Indexb1
        End Operator 'CType

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_max_num As Integer)
            Me.pintMAX_NUM = ur_max_num
        End Sub

        Public Shadows ReadOnly Property Current() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me.pintCUR_NUM
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function GetEnumerator() As RCTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public ReadOnly Property Indexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexb1 = Me.pintCUR_NUM
            End Get
        End Property

        Public ReadOnly Property Indexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexenm = b0(Me.pintCUR_NUM)
            End Get
        End Property

        Public ReadOnly Property LastIndexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexb1 = Me.pintMAX_NUM
            End Get
        End Property

        Public ReadOnly Property LastIndexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexenm = b0(Me.pintMAX_NUM)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function MoveNext() As Boolean
            MoveNext = (Me.pintCUR_NUM < Me.pintMAX_NUM)
            Me.pintCUR_NUM += 1
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Reset() As RCTR
            Reset = Me
            Me.pintCUR_NUM = 0
        End Function
    End Class 'RCTR

    Public Class SDACTR
        Inherits RCTR

        Private psdaLIST As Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdata As Sdata)
            Call MyBase.New(ur_sdata.Count)
            Me.psdaLIST = ur_sdata
        End Sub

        Public Shadows ReadOnly Property Current() As SDACTR
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDACTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.psdaLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDACTR

    Public Class Sdata
        Inherits System.Collections.Generic.List(Of String)

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_val As String) As Sdata
            d = Me
            Call Me.Add(ur_val)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ParamArray ur_val() As String) As Sdata
            dList = Me
            If ur_val IsNot Nothing Then
                For Each strENTRY In ur_val
                    If strENTRY Is Nothing Then
                        strENTRY = mt
                    End If

                    Call Me.Add(strENTRY)
                Next strENTRY
            End If
        End Function 'dList

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As Sdata
            gCopy = New Sdata().dList(Me.ToArray)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDACTR
            kvp = New SDACTR(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Split(ur_text As String, ur_sprtr As Char) As Sdata
            Dim sdaCMP = New Sdata
            Split = sdaCMP
            For Each strTEXT In ur_text.Split(ur_sprtr)
                sdaCMP.Add(strTEXT)
            Next
        End Function 'Split

        Public Property v_b1(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property v_enm(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Sdata

    Public Class Strap
        Private pstbTEXT As System.Text.StringBuilder

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            Me.pstbTEXT = New System.Text.StringBuilder
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(b As Strap) As String
            Return b.ToString
        End Operator

        <System.Diagnostics.DebuggerHidden()>
        Public Function Clear() As Strap
            Clear = Me
            Call Me.pstbTEXT.Clear()
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_text As String) As Strap
            d = Me.dSprtr(mt, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSV_Quoted(ur_index_b1 As Integer, ur_text As String) As Strap
            dCSV_Quoted = Me
            If ur_index_b1 > 1 Then
                Me.d(",")
            End If

            Me.d(qs).d(ur_text.Replace(qs, qs & qs)).d(qs)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ur_sprtr As String, ParamArray ur_text() As String) As Strap
            dList = Me
            If ur_text IsNot Nothing Then
                For Each strENTRY In ur_text
                    Call Me.dSprtr(ur_sprtr, strENTRY)
                Next strENTRY
            End If
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSVList(ParamArray ur_text() As String) As Strap
            dCSVList = Me
            If ur_text IsNot Nothing Then
                For ENTCTR = 0 To UBound(ur_text)
                    Me.dCSV_Quoted(ENTCTR + 1, ur_text(ENTCTR))
                Next ENTCTR
            End If
        End Function 'dCSVList

        <System.Diagnostics.DebuggerHidden()>
        Public Function dLine(Optional ur_text As String = "") As Strap
            dLine = Me.dSprtr(vbCrLf, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dS(ur_text As String) As Strap
            dS = Me.dSprtr(s, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dSprtr(ur_sprtr As String, ur_text As String) As Strap
            dSprtr = Me
            Me.pstbTEXT.Append(ur_sprtr).Append(ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function gCopy(ur_text As String) As Strap
            gCopy = New Strap().d(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText() As Boolean
            HasText = (Me.Length > 0)
        End Function

        Public ReadOnly Property Length As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Length = Me.pstbTEXT.Length
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function r1(ur_text As String) As Strap
            r1 = Me
            Call Me.pstbTEXT.Replace("@r1", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function r2(ur_text As String) As Strap
            r2 = Me
            Call Me.pstbTEXT.Replace("@r2", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function rx(ur_index As Integer, ur_text As String) As Strap
            rx = Me
            Call Me.pstbTEXT.Replace("@r" & ur_index, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = Me.pstbTEXT.ToString
        End Function
    End Class 'Strap

    Public Class bitBASE
        Public name As String
        Public seq As Integer
    End Class

    Public Class TRow(Of T As {New, bitBASE})
        Inherits Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            For Each intVAL In Me.RefColNames
                Me.Add(mt)
            Next
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Index_TableSplit(ur_table As Objlist(Of TRow(Of T)), ur_key As T) As SdPair(Of Objlist(Of TRow(Of T)))
            Dim sdpRET = New SdPair(Of Objlist(Of TRow(Of T)))
            Index_TableSplit = sdpRET
            Dim tblCHUNK As Objlist(Of TRow(Of T)) = Nothing
            For Each rowCHUNK In ur_table
                Dim strINDEX = rowCHUNK.v(ur_key)
                Dim intFOUND = sdpRET.IndexOf(strINDEX)
                If intFOUND < 0 Then
                    tblCHUNK = New Objlist(Of TRow(Of T))
                    sdpRET.d(strINDEX, tblCHUNK)
                Else
                    tblCHUNK = sdpRET.l_enm(intFOUND)
                End If

                tblCHUNK.Add(rowCHUNK)
            Next rowCHUNK

            Call sdpRET.Sort()
        End Function 'Index_TableSplit


        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As TRow(Of T)
            Dim sdaRET = New TRow(Of T)
            gCopy = sdaRET
            For Each kvpENTRY In Me.kvp
                sdaRET.v_enm(kvpENTRY.Indexenm) = kvpENTRY.v
            Next kvpENTRY
        End Function

        Public Function Link_Table(ur_table As Objlist(Of TRow(Of T)), ParamArray ur_key_list() As T) As Objlist(Of TRow(Of T))
            Dim tblRET = New Objlist(Of TRow(Of T))
            Link_Table = tblRET
            For Each rowCHUNK In ur_table
                Dim bolFOUND = True
                For Each intKEY In ur_key_list
                    If AreEqual(rowCHUNK.v(intKEY), Me.v(intKEY)) = False Then
                        bolFOUND = False
                        Exit For
                    End If
                Next intKEY

                If bolFOUND Then
                    tblRET.Add(rowCHUNK)
                End If
            Next rowCHUNK
        End Function 'Link_Table

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function PersistRead(ur_persist_path As String) As Objlist(Of TRow(Of T))
            Dim ttbRET = New Objlist(Of TRow(Of T))
            PersistRead = ttbRET
            If Mx.glbl.gWindowsFS.HasFile(ur_persist_path) Then
                Dim bolFIRST_LINE = True
                Dim lstREF_COL = New Objlist(Of T)
                Using stmIN_FILE = Mx.glbl.gWindowsFS.ReadStream(ur_persist_path)
                    Dim strLINE = mt
                    While stmIN_FILE.EndOfStream = False
                        strLINE &= stmIN_FILE.ReadLine
                        Dim bolBALANCED_QUOTES = True
                        For CHRCTR = 0 To strLINE.Length - 1
                            If strLINE(CHRCTR) = """"c Then
                                bolBALANCED_QUOTES = Not bolBALANCED_QUOTES
                            End If
                        Next CHRCTR

                        If bolBALANCED_QUOTES = False Then
                            strLINE &= vbCrLf

                        Else
                            Dim new_row = New TRow(Of T)
                            If Left(strLINE, 1) = vbLf Then
                                strLINE = Mid(strLINE, 2)
                            End If

                            If bolFIRST_LINE = True Then
                                bolFIRST_LINE = False
                                Dim bolCOL_MATCH = False
                                Dim sdaFIRST_ROW = MxText.CSVSplit(strLINE, vbTab)
                                For Each strENTRY In MxText.CSVSplit(strLINE, vbTab)
                                    Dim enmFOUND_KEY As T = Nothing
                                    For Each enmKEY In new_row.RefColKeys
                                        If AreEqual(enmKEY.name, strENTRY) Then
                                            enmFOUND_KEY = enmKEY
                                            bolCOL_MATCH = True
                                            Exit For
                                        End If
                                    Next enmKEY

                                    lstREF_COL.Add(enmFOUND_KEY)
                                Next strENTRY

                                If bolCOL_MATCH = False Then
                                    Exit While
                                End If

                            ElseIf HasText(strLINE) Then
                                For Each kvpCOL In MxText.CSVSplit(strLINE, vbTab).kvp
                                    Dim enmKEY = lstREF_COL.Item(kvpCOL.Indexenm)
                                    If enmKEY IsNot Nothing Then
                                        new_row.v(enmKEY) = kvpCOL.v
                                    End If
                                Next kvpCOL

                                ttbRET.Add(new_row)
                            End If 'bolFIRST_LINE

                            strLINE = mt
                        End If 'bolBALANCED_QUOTES
                    End While
                End Using 'stmIN_FILE
            End If 'ur_persist_path
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Sub PersistWrite(ur_table As Objlist(Of TRow(Of T)), ur_persist_path As MxText.FileName)
            If Mx.glbl.gWindowsFS.HasDir(ur_persist_path.gParentDir) = False Then
                Mx.glbl.gWindowsFS.CreateDirectory(ur_persist_path.gParentDir)
            End If

            Using stmOUT_FILE = Mx.glbl.gWindowsFS.WriteStream(ur_persist_path)
                For Each kvpROW In ur_table.kvp
                    stmOUT_FILE.Write(kvpROW.row.ToString(kvpROW.Indexb1 = 1, True))
                Next
            End Using 'stmOUT_FILE
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeys() As Objlist(Of T)
            RefColKeys = TRow(Of T).glbl.RefKeys
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeySearch(ur_name As String) As Objlist(Of T)
            RefColKeySearch = TRow(Of T).glbl.RefKeySearch(ur_name)
        End Function 'RefColKeySearch

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColNames() As Sdata
            RefColNames = TRow(Of T).glbl.RefNames
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ToCbrd(ur_hdr As Boolean) As Integer
            ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean, Optional ur_quoted As Boolean = False) As Strap
            Dim stpRET = New Strap
            ToString = stpRET
            If ur_hdr Then : For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : stpRET.d(kvpCOL.v) : Next kvpCOL : stpRET.dLine() : End If
            For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : If ur_quoted Then : stpRET.d(qs).d(Me.v_enm(kvpCOL.Indexenm).Replace(qs, qs & qs)).d(qs) : Else : stpRET.d(Me.v_enm(kvpCOL.Indexenm)) : End If : Next kvpCOL : stpRET.dLine()
        End Function


        Public Property v(ur_cl As T) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.Item(ur_cl.seq)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = ""
                End If

                Me.Item(ur_cl.seq) = ur_val
            End Set
        End Property

        Public Class glbl
            Private Shared sdaTCOL_NAME As Sdata
            Private Shared sdjTCOL_KEY As Objlist(Of T)

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME Is Nothing Then
                    Dim objTEST = GetType(T).GetFields()(0).GetValue(Nothing)
                End If

                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME IsNot Nothing Then
                    sdjTCOL_KEY = New Objlist(Of T)
                    Dim tpeCMP = GetType(T)
                    For Each kvpCOL In sdaTCOL_NAME.kvp
                        For Each objPROP In tpeCMP.GetFields()
                            If tpeCMP.DeclaringType Is tpeCMP Then
                                Dim objBIT = DirectCast(objPROP.GetValue(Nothing), bitBASE)
                                If objBIT.seq = kvpCOL.Indexenm Then
                                    sdjTCOL_KEY.Add(DirectCast(objPROP.GetValue(Nothing), T))
                                    Exit For
                                End If
                            End If 'tpeCMP
                        Next objPROP
                    Next kvpCOL
                End If 'sdaTCOL_NAME
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Function NewProp() As T
                Dim objRET = New T
                NewProp = objRET

                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Function 'NewProp

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub NewProp(ur_prop As T)
                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function NewBitBase() As T
                NewBitBase = glbl.NewProp()
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub NewBitBase(ur_prop As T)
                Call glbl.NewProp(ur_prop)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeys() As Objlist(Of T)
                Call glbl.Init()
                RefKeys = glbl.sdjTCOL_KEY
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeySearch(ur_name As String) As Objlist(Of T)
                Call glbl.Init()
                Dim ttbRET = New Objlist(Of T)
                RefKeySearch = ttbRET
                Dim intFOUND_INDEX = TRow(Of T).glbl.RefNames.IndexOf(ur_name)
                If intFOUND_INDEX >= b0(1) Then
                    ttbRET.Add(TRow(Of T).glbl.RefKeys(intFOUND_INDEX))
                End If
            End Function 'RefKeySearch

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefNames() As Sdata
                Call glbl.Init()
                RefNames = glbl.sdaTCOL_NAME
            End Function

            Public Class Trbase(Of W As {New, T})
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function NewBitBase() As W
                    Dim objRET = New W
                    NewBitBase = objRET
                    Call TRow(Of T).glbl.NewBitBase(objRET)
                End Function
            End Class 'Trbase
        End Class 'glbl
    End Class 'Trow

    Partial Public Class MxText 'Parse
        Public Class enmCMD_RET
            Inherits bitBASE
            Public Shared eq As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared fslash As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs_end As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared txt As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared unk As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared ws As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
        End Class

        Public Class Cmdline_UB(Of T As {New, bitBASE}, W As {New, bitBASE})
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                CommandLine_UBParm = prv.CommandLine_UBParm(ur_ub_key, ur_ub_val, ur_source_text, ur_default_field_list)
            End Function

            Class sCMDLINE
                Inherits Mx.Objlist(Of TRow(Of enmCMD_RET))

                <System.Diagnostics.DebuggerHidden()>
                Public Overloads Function ToString(ur_hdr As Boolean) As String
                    Dim stpRET = Strapd() : For Each kvpREC In Me.kvp : stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr)) : Next kvpREC : ToString = stpRET
                End Function 'ToString
                <System.Diagnostics.DebuggerHidden()>
                Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                End Function
            End Class 'sCMDLINE

            Class sCMD_RET
                Public ttbUB_PARM As Objlist(Of TRow(Of W))
                Public ttbCMD_PARM As sCMDLINE
            End Class

            Partial Private Class prv
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                    Dim objRET = New sCMD_RET
                    CommandLine_UBParm = objRET
                    objRET.ttbUB_PARM = New Objlist(Of TRow(Of W))
                    objRET.ttbCMD_PARM = New sCMDLINE
                    Dim rowCMD_PARM = New TRow(Of enmCMD_RET)
                    objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                    Dim sdaDEFAULT_PARMNAME = New Sdata
                    Dim sdaDEST_PARMS = TRow(Of T).glbl.RefNames
                    For Each intUN In ur_default_field_list
                        sdaDEFAULT_PARMNAME.d(intUN.name)
                    Next

                    Dim stpCOMPILE = Strapd()
                    Dim intPREV_CHUNK = enmCMD_RET.ws
                    Dim intCHUNK_C = enmCMD_RET.ws
                    For CHRCTR = 0 To ur_source_text.Length - 1
                        Dim chrC = ur_source_text(CHRCTR)
                        intCHUNK_C = gChunkType(chrC)
                        Dim intSPAN = 1
                        For SPNCTR = CHRCTR + 1 To ur_source_text.Length - 1
                            Dim chrS = ur_source_text(SPNCTR)
                            Dim intSPAN_C = gChunkType(chrS)
                            If intSPAN_C IsNot intCHUNK_C OrElse
                              intSPAN_C Is enmCMD_RET.qs Then
                                'Combine all chunks except for escaped quotes
                                intSPAN = SPNCTR - CHRCTR
                                Exit For
                            End If

                            If SPNCTR = ur_source_text.Length - 1 Then
                                intSPAN = SPNCTR + 1 - CHRCTR
                                Exit For
                            End If
                        Next SPNCTR

                        Dim strCHUNK = ur_source_text.Substring(CHRCTR, intSPAN)
                        If intPREV_CHUNK Is enmCMD_RET.ws Then
                            'Have ws, skip compiled ws; wait for fslash or default parm
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'skip compiled fslash
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip ws between parameters

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'compile unquoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = enmCMD_RET.txt
                                stpCOMPILE.Clear.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.fslash Then
                            'Have ws-fslash, compile txt parm name; wait for eq
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'qs between parm name and eq is unk
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq Then
                                'skip compile qe
                                rowCMD_PARM.v(enmCMD_RET.fslash) = stpCOMPILE.ToString
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = enmCMD_RET.eq

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'compile txt into parm name
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.eq Then
                            'Have ws-fslash-eq, skip compile; wait for txt
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'flush parameter as "=true"; start new parameter
                                stpCOMPILE.Clear.d("true")
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted parameter value
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'keep ws in eq

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'skip eq between paramater name and value

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'store param name, compile unquoted parameter value
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.txt Then
                            'Have ws-fslash-eq-txt, compile parm val; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                'Keep fslash and qs in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'Keep eq in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs Then
                            'Have ws-fslash-eq-qs, compile parm val; wait for qs_end
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'Keep fslash in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'hold parameter; skip this qs and look for another escaped qs or flush the parameter
                                intPREV_CHUNK = enmCMD_RET.qs_end

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'Keep ws, eq and txt in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs_end Then
                            'Have ws-fslash-eq-qs-qsend, compile parm val without ending quote; wait for qs or ws
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'qs_end then fslash without ws between is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'keep escaped qs
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'qs_end then ws or txt is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.unk Then
                            'Have unk, skip compile; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip parameter; start new parameter
                                rowCMD_PARM.v(enmCMD_RET.txt) = stpCOMPILE.ToString
                                rowCMD_PARM = New TRow(Of enmCMD_RET)
                                objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If
                        End If

                        CHRCTR += intSPAN - 1

                        If CHRCTR = ur_source_text.Length - 1 Then
                            'On last entry
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse intCHUNK_C Is enmCMD_RET.eq Then
                                'flush default parameter value
                                stpCOMPILE.Clear.d("true")
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs OrElse intCHUNK_C Is enmCMD_RET.txt Then
                                'flush parameter
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip trailing ws
                            End If
                        End If
                    Next CHRCTR
                End Function 'CommandLine_Chunk

                Private Class Flush_Ret
                    Public rowCMD_PARM As TRow(Of enmCMD_RET)
                    Public intPREV_CHUNK As enmCMD_RET
                End Class

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function Flush_Parameter(ur_ub_key As W, ur_ub_val As W, ur_cmdparm_row As TRow(Of enmCMD_RET), ur_parm_val As Strap, ur_new_prevchunk As enmCMD_RET, ur_refname_list As Sdata, ur_objret_arl As sCMD_RET) As Flush_Ret
                    Dim objRET = New Flush_Ret
                    Flush_Parameter = objRET
                    objRET.rowCMD_PARM = New TRow(Of enmCMD_RET)
                    ur_objret_arl.ttbCMD_PARM.Add(objRET.rowCMD_PARM)
                    objRET.intPREV_CHUNK = ur_new_prevchunk
                    'flush parameter
                    ur_cmdparm_row.v(enmCMD_RET.txt) = ur_parm_val
                    Dim intFOUND = ur_refname_list.IndexOf(ur_cmdparm_row.v(enmCMD_RET.fslash).ToLower)
                    If intFOUND >= 0 Then
                        With 1 : Dim sdaROW = New TRow(Of W)
                            sdaROW.v(ur_ub_key) = ur_refname_list.v_enm(intFOUND)
                            sdaROW.v(ur_ub_val) = ur_cmdparm_row.v(enmCMD_RET.txt)
                            ur_objret_arl.ttbUB_PARM.Add(sdaROW)
                        End With

                        'Skip parameter if not found
                    End If

                    ur_parm_val.Clear()
                End Function

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function gChunkType(ur_char As Char) As enmCMD_RET
                    If ur_char = vbCr OrElse
                  ur_char = vbLf OrElse
                  ur_char = " "c OrElse
                  ur_char = vbTab Then
                        gChunkType = enmCMD_RET.ws

                    ElseIf ur_char = "="c OrElse
                  ur_char = ":"c Then
                        gChunkType = enmCMD_RET.eq

                    ElseIf ur_char = "/"c Then
                        gChunkType = enmCMD_RET.fslash

                    ElseIf ur_char = """"c Then
                        gChunkType = enmCMD_RET.qs

                    Else
                        gChunkType = enmCMD_RET.txt
                    End If
                End Function 'gChunkType
            End Class 'prv
        End Class
    End Class 'MxText-Parse

    Partial Public Class MxText
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function CSVSplit(ByVal ur_line As String, Optional ur_separator As String = ",") As Sdata
            Dim sdaCMP = New Sdata
            CSVSplit = sdaCMP
            Dim objARRAY = ur_line.ToCharArray
            Dim objSPRTR = Mid(ur_separator, 1, 1).ToCharArray()(0)
            Dim objESCAPE_QUOTE = """"c

            Const cstSTART = 0
            Const cstESC = 1
            Const cstQS = 2
            Dim intPARSE_STATE = cstSTART
            Dim intLEN = Len(ur_line) - 1
            Dim stpFIELD As New Strap
            For intIX = 0 To intLEN
                Dim objCHR = objARRAY(intIX)
                Select Case intPARSE_STATE
                    Case cstESC
                        stpFIELD.d(objCHR)
                        intPARSE_STATE = cstQS

                    Case cstQS
                        If objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstSTART
                            Dim intNEXT_IX = intIX + 1
                            If intNEXT_IX < intLEN Then
                                If objARRAY(intNEXT_IX) = objESCAPE_QUOTE Then
                                    intPARSE_STATE = cstESC
                                End If 'intNEXT_IX
                            End If 'intNEXT_IX

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR

                    Case cstSTART
                        If objCHR = objSPRTR Then
                            sdaCMP.d(stpFIELD.ToString)
                            Call stpFIELD.Clear()

                        ElseIf objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstQS

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR
                End Select 'intPARSE_STATE
            Next intIX

            sdaCMP.d(stpFIELD)
        End Function 'CSVSplit
    End Class 'MxText-Csv

    Public Class MxText
        Public Class FileName
            Public FilePath As String
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.FilePath = mt
            End Sub 'New
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(ur_path As String)
                Me.FilePath = ur_path
            End Sub 'New

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As FileName) As String
                Return b.FilePath
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As String) As FileName
                Return New FileName(b)
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shadows Function ToString() As String
                ToString = Me.FilePath
            End Function 'ToString

            <System.Diagnostics.DebuggerHidden()>
            Public Function dAppendEXT(ur_ext As String) As FileName
                dAppendEXT = Me
                If ur_ext.StartsWith(".") = False Then
                    ur_ext = "." & ur_ext
                End If

                Me.FilePath &= ur_ext
            End Function 'dAppendEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function d(ur_file_name As String) As FileName
                d = Me
                If HasText(Me.FilePath) Then
                    Me.FilePath = System.IO.Path.Combine(Me.FilePath, ur_file_name)

                Else 'Me
                    Me.FilePath = ur_file_name
                End If 'Me
            End Function 'd

            <System.Diagnostics.DebuggerHidden()>
            Public Function dNowTextYMDHMS(ur_file_name As String, Optional ur_separator As String = "_") As FileName
                dNowTextYMDHMS = Me
                Me.d(ur_file_name & ur_separator & Now().ToString("yyyy\mMM\dddthh\mmm\sss").Replace("P12", "N12").Replace("A12", "A00").ToLower)
            End Function 'dNowTextYMDHMS

            Public Property Ext() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Ext = System.IO.Path.GetExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wEXT(value)
                End Set
            End Property 'Ext

            Public ReadOnly Property ExtAll() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ExtAll = Strapd().dList(mt, Me.ExtList.ToArray)
                End Get
            End Property 'ExtAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function ExtList() As Sdata
                Dim sdaDESC = Sdata.Split(Me.FilePath, "."c)
                ExtList = sdaDESC
                sdaDESC.RemoveAt(0)
                For Each ROWCTR In sdaDESC.kvp
                    sdaDESC.v_b1(ROWCTR) = "." & sdaDESC.v_b1(ROWCTR)
                Next ROWCTR
            End Function 'ExtList

            Public Property FileGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileGroup = System.IO.Path.GetFileNameWithoutExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.Ext
                End Set
            End Property 'FileGroup

            Public Property FileBaseGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileBaseGroup = mt
                    For Each strENTRY In Sdata.Split(Me.Name, "."c)
                        FileBaseGroup = strENTRY
                        Exit For
                    Next
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.ExtAll
                End Set
            End Property 'FileBaseGroup

            <System.Diagnostics.DebuggerHidden()>
            Public Function gCopy() As FileName
                gCopy = New FileName(Me)
            End Function 'gCopy

            <System.Diagnostics.DebuggerHidden()>
            Public Function gFullPath() As FileName
                gFullPath = New FileName(glbl.gWindowsFS.GetFullPath(Me.FilePath))
            End Function 'gFullPath

            <System.Diagnostics.DebuggerHidden()>
            Public Function gParentDir() As FileName
                gParentDir = New FileName(Me.ParentDir)
            End Function 'gParentDir

            Public Property Name() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Name = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If

                    If HasText(strPATH) Then
                        Name = System.IO.Path.GetFileName(strPATH)
                    End If
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wParentDir.d(value)
                End Set
            End Property 'Name

            Public Property ParentDir() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ParentDir = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If 'strPATH

                    If HasText(strPATH) Then
                        ParentDir = System.IO.Path.GetDirectoryName(strPATH)
                    End If 'strPATH
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Dim strFILE_NAME = Me.Name
                    If HasText(value) Then
                        Me.FilePath = System.IO.Path.Combine(value, strFILE_NAME)

                    Else 'value
                        Me.FilePath = strFILE_NAME
                    End If 'value
                End Set
            End Property 'ParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function ParentList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH = Me.PathList
                ParentList = sdaPATH
                sdaPATH.RemoveAt(b0(sdaPATH.Count))
            End Function 'ParentList

            <System.Diagnostics.DebuggerHidden()>
            Public Function PathList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH As New System.Collections.Generic.List(Of FileName)
                PathList = sdaPATH

                Dim sdaDESC = New Objlist(Of FileName)
                sdaDESC.Add(Me.gCopy)
                Dim objREDUCE = Me.gCopy
                Call objREDUCE.wParentDir()
                While HasText(objREDUCE.FilePath)
                    sdaDESC.Add(objREDUCE.gCopy)
                    Call objREDUCE.wParentDir()
                End While 'objREDUCE

                For Each objFILE In sdaDESC
                    sdaPATH.Add(objFILE)
                Next objFILE
            End Function 'PathList

            <System.Diagnostics.DebuggerHidden()>
            Public Function wAssemblyDir(ur_assembly_info As Microsoft.VisualBasic.ApplicationServices.AssemblyInfo) As FileName
                wAssemblyDir = Me
                Me.FilePath = ur_assembly_info.DirectoryPath.Replace("\bin\Debug", mt)
            End Function 'wAssemblyDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wClear() As FileName
                wClear = Me
                Me.FilePath = mt
            End Function 'wClear

            <System.Diagnostics.DebuggerHidden()>
            Public Function wEXT(ur_ext As String) As FileName
                wEXT = Me
                Dim strFILE_NAME = Me.FileGroup
                If Left(ur_ext, 1) <> "." Then
                    ur_ext = "." & ur_ext
                End If 'ur_ext

                Me.wParentDir.d(strFILE_NAME & ur_ext)
            End Function 'wEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function wParentDir() As FileName
                wParentDir = Me
                Me.FilePath = Me.ParentDir
            End Function 'wParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wTempFileName(ur_fs_proxy As Microsoft.VisualBasic.MyServices.FileSystemProxy) As FileName
                wTempFileName = Me
                Me.FilePath = ur_fs_proxy.GetTempFileName
                Call ur_fs_proxy.DeleteFile(Me.FilePath)
            End Function 'wTempFileName
        End Class 'FileName
    End Class 'MxText-FileName

    Partial Public Class glbl
        Public Class gCboard
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Clear()
                Call My.Computer.Clipboard.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetText() As String
                GetText = My.Computer.Clipboard.GetText
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function SetText(ur_text As String) As Integer
                If HasText(ur_text) Then
                    Call My.Computer.Clipboard.SetText(ur_text)
                    SetText = 1 + ur_text.Length - ur_text.Replace(vbLf, mt).Length
                Else
                    Call My.Computer.Clipboard.Clear()
                    SetText = 0
                End If
            End Function 'SetText
        End Class 'gCboard

        Public Class gDiagnostics
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function IsRunningWindow(ur_title As String) As Boolean
                IsRunningWindow = False
                For Each objCUR_PROC In System.Diagnostics.Process.GetProcesses()
                    If objCUR_PROC.MainWindowHandle.ToInt32 <> 0 AndAlso
                      AreEqual(objCUR_PROC.MainWindowTitle, ur_title) Then
                        IsRunningWindow = True
                        Exit For
                    End If
                Next objCUR_PROC
            End Function 'IsRunningWindow

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Read_CommandLineText(ur_exec_path As String, ur_exec_param As String) As String
                Dim prcCOMMAND_LINE = gDiagnostics.Start_CommandLine_Program(ur_exec_path, ur_exec_param)
                Read_CommandLineText = prcCOMMAND_LINE.StandardOutput.ReadToEnd()
                prcCOMMAND_LINE.WaitForExit()
            End Function 'Read_CommandLineText

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Start_CommandLine_Program(ur_exec_path As String, ur_exec_param As String) As System.Diagnostics.Process
                Dim retPROCESS As New System.Diagnostics.Process()
                Start_CommandLine_Program = retPROCESS
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.UseShellExecute = False
                    prcINFO.RedirectStandardOutput = True
                    prcINFO.RedirectStandardError = True
                    prcINFO.CreateNoWindow = True
                End With 'prcINFO

                retPROCESS.Start()
            End Function 'Start_Procses

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Start_Windows_Program(ur_exec_path As String, ur_exec_param As String)
                Dim retPROCESS As New System.Diagnostics.Process()
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.Verb = "Open"
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
                    prcINFO.UseShellExecute = True
                End With 'prcINFO

                retPROCESS.Start()
            End Sub 'Start_Procses
        End Class 'gDiagnostics

        Public Class gInteraction
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub AppActivate(ur_window_title As String)
                Microsoft.VisualBasic.Interaction.AppActivate(ur_window_title)
            End Sub
        End Class 'gInteraction

        Public Class gEnvironment
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine() As String
                CommandLine = System.Environment.CommandLine
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ExpandEnvironmentVariables(ur_path As String) As String
                ExpandEnvironmentVariables = System.Environment.ExpandEnvironmentVariables(ur_path)
            End Function
        End Class 'gEnvironment

        Public Class gMsgBox
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetResult(ur_message As String, ur_style As MsgBoxStyle, ur_title As String) As MsgBoxResult
                GetResult = MsgBox(ur_message, ur_style, ur_title)
            End Function
        End Class 'gMsgBox

        Public Class gThread
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Sleep(ur_milliseconds As Integer)
                System.Threading.Thread.Sleep(ur_milliseconds)
            End Sub
        End Class 'gThread

        Public Class gWindowsFS
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Copy(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Copy(ur_source_path, ur_dest_path, True)
            End Sub
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub CreateDirectory(ur_folder_path As String)
                System.IO.Directory.CreateDirectory(ur_folder_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Delete(ur_path As String)
                System.IO.File.Delete(ur_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = System.IO.Directory.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetDirectories(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetDirectories = System.IO.Directory.GetDirectories(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFullPath(ur_partial_path As String) As String
                GetFullPath = System.IO.Path.GetFullPath(ur_partial_path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasDir(ur_search_folder As String) As Boolean
                HasDir = System.IO.Directory.Exists(ur_search_folder)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasFile(ur_search_Path As String) As Boolean
                HasFile = System.IO.File.Exists(ur_search_Path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Move(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Move(ur_source_path, ur_dest_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadAllText(ur_file_path As String) As String
                ReadAllText = System.IO.File.ReadAllText(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadStream(ur_file_path As String) As System.IO.StreamReader
                ReadStream = New System.IO.StreamReader(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub WriteAllText(ur_file_path As String, ur_text As String)
                Call System.IO.File.WriteAllText(ur_file_path, ur_text, Mx.gUTF8_FileEncoding())
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function WriteStream(ur_file_path As String) As System.IO.StreamWriter
                WriteStream = New System.IO.StreamWriter(ur_file_path, False, Mx.gUTF8_FileEncoding())
            End Function
        End Class 'gWindowsFS
    End Class 'glbl

    Public Class TablePKEnum(Of E As {New, bitBASE}, P As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of P, T)
        Private PK As E

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_flag_populate_keys As Boolean = True)
            Me.ttb = New System.Collections.Generic.Dictionary(Of P, T)
            Me.PK = TRow(Of E).glbl.RefKeys.tr_b1(1)
            If ur_flag_populate_keys Then
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    Dim new_row = New T
                    new_row.v(Me.PK) = enmENTRY.name
                    Me.ttb.Add(enmENTRY, new_row)
                Next enmENTRY
            End If 'ur_empty_table
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ur_key As P) As Boolean
            ExistsKey = Me.ttb.ContainsKey(ur_key)
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim enmENTRY = prv.Get_PKStr(Me, ur_row)
            If enmENTRY Is Nothing Then
                Throw New System.Exception("Primary Key must exist in the enumeration: " & ur_row.v(Me.PK))

            ElseIf Me.ttb.ContainsKey(enmENTRY) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_row.v(Me.PK))

            Else
                Me.ttb.Add(enmENTRY, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            InsKey = ret
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKEnum(Of E, P, T)
            Dim ttbRET = New TablePKEnum(Of E, P, T)
            PersistRead = ttbRET
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Me.Ins(CType(row, T))
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T()
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ur_key As P) As T
            SelKey = Me.ttb.Item(ur_key)
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                ret = Me.ttb.Item(ur_key)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            UseKey = ret
        End Function 'UseKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        Private Class prv
            Public Shared Sub Assign_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T, ur_key As P)
                ur_row.v(ur_table.PK) = ur_key.name
            End Sub 'Assign_PKStr

            Public Shared Function Get_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T) As P
                Dim ret As P = Nothing
                Dim strPK = ur_row.v(ur_table.PK)
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    If AreEqual(enmENTRY.name, strPK) Then
                        ret = enmENTRY
                        Exit For
                    End If
                Next enmENTRY

                Get_PKStr = ret
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKEnum

    Public Class TablePKStr(Of E As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of String, T)
        Private PK As Objlist(Of E)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_pk_count As Integer)
            Me.ttb = New System.Collections.Generic.Dictionary(Of String, T)
            Me.PK = New Objlist(Of E)
            With 1 : Dim lstKEYS = TRow(Of E).glbl.RefKeys
                Dim intPK_COUNT = ur_pk_count
                If intPK_COUNT > lstKEYS.Count Then
                    intPK_COUNT = lstKEYS.Count
                End If

                For KEYCTR = 1 To ur_pk_count
                    Me.PK.Add(lstKEYS.Item(b0(KEYCTR)))
                Next
            End With 'lstKEYS
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ParamArray ur_key() As String) As Boolean
            ExistsKey = False
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("ExistsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                ExistsKey = Me.ttb.ContainsKey(strPK_KEY_COMBINED)
            End If 'ur_key
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function DelAll() As TablePKStr(Of E, T)
            DelAll = Me
            Call Me.ttb.Clear()
        End Function 'DelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_row)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

            Else
                Me.ttb.Add(strPK_KEY_COMBINED, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("InsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

                Else
                    ret = New T
                    Call prv.Assign_PKStr(Me, ret, ur_key)
                    Me.ttb.Add(strPK_KEY_COMBINED, ret)
                End If 'Me
            End If 'ur_key

            InsKey = ret
        End Function 'InsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKStr(Of E, T)
            PersistRead = Me
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Dim new_row = New T
                For Each enmENTRY In new_row.RefColKeys
                    new_row.v(enmENTRY) = row.v(enmENTRY)
                Next

                Me.Ins(new_row)
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("SelKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    ret = Me.ttb.Item(strPK_KEY_COMBINED)

                Else
                    ret = New T
                End If 'Me
            End If 'ur_key

            SelKey = ret
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelOnKey(ParamArray ur_key() As String) As TablePKStr(Of E, T)
            Dim ret = Me
            For KEYCTR = 1 To Me.PK.Count
                ret = ret.Sel(Me.PK.Item(b0(KEYCTR)), ur_key(b0(KEYCTR)))
            Next

            SelOnKey = ret
        End Function 'SelOnKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                ret = Me.ttb.Item(strPK_KEY_COMBINED)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(strPK_KEY_COMBINED, ret)
            End If

            UseKey = ret
        End Function 'UseKey

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Assign_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T, ur_key() As String)
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                For KEYCTR = 1 To intPK_KEYS
                    ur_row.v(ur_table.PK.Item(b0(KEYCTR))) = ur_key(b0(KEYCTR))
                Next
            End Sub 'Assign_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_key() As String) As String
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To intPK_KEYS
                    If KEYCTR = 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_key(b0(KEYCTR)).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T) As String
                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To ur_table.PK.Count
                    If KEYCTR > 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_row.v_b1(KEYCTR).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKStr


    Partial Public Class Have
        Partial Private Class prv_sample
            Private Class Have
                Private Shared tblUserBowl As sUserBowl

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Sub Connect()
                    If Have.tblUserBowl Is Nothing Then
                        Have.tblUserBowl = New sUserBowl
                    End If 'sdaTCOL_NAME
                End Sub 'Connect

                Public Class enmUB
                    Inherits bitBASE
                    Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                    Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                End Class

                Public Class enmUN
                    Inherits bitBASE
                    Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p1 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p2 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared to_clipboard As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                End Class

                'Public Shared Function UserBowl() As sUserBowl
                '    Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
                '    Call Have.Connect()
                '    UserBowl = Have.tblUserBowl
                '    If bolFIRST_INIT Then
                '        Call Have.tblUserBowl.InsFrom_Application()
                '        Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                '        Call Have.tblUserBowl.Cboard_CmdlineAudit()
                '    End If
                'End Function 'UserBowl

                Public Class rUserBowl
                    Inherits TRow(Of enmUB)

                    <System.Diagnostics.DebuggerHidden()>
                    Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                        vt = Me
                        Me.v(ur_enm) = ur_val
                    End Function

                    'Public Shadows Function Link_Table(ur_child_table As Have.sReport_Detl, ParamArray ur_key_list() As bitRP) As sReport_Detl
                    '    Dim tblRET = New sReport_Detl
                    '    Link_Table = tblRET
                    '    Dim sdpXLAT = New SdPair(Of bitRT)
                    '    Dim stpKEY_BINDINGS = Strapd()
                    '    For Each keyRP In ur_key_list
                    '        stpKEY_BINDINGS.dS(keyRP.name)
                    '        For Each keyRT In ur_child_table.SelFirst.RefColKeys
                    '            If AreEqual(keyRT.name, keyRP.name) Then
                    '                sdpXLAT.d(keyRP.name, keyRT)
                    '            End If
                    '        Next keyRT
                    '    Next keyRP

                    '    If sdpXLAT.Count <> ur_key_list.Length Then
                    '        Throw New System.Exception("Key bindings not found for RT/RP join: " & stpKEY_BINDINGS.ToString)

                    '    Else
                    '        For Each trwJOIN In ur_child_table.SelAll
                    '            Dim bolFOUND = True
                    '            For Each keyRP In ur_key_list
                    '                Dim keyRT = sdpXLAT.l(keyRP.name)
                    '                If AreEqual(trwJOIN.v(keyRT), Me.v(keyRP)) = False Then
                    '                    bolFOUND = False
                    '                    Exit For
                    '                End If
                    '            Next keyRP

                    '            If bolFOUND Then
                    '                tblRET.Ins(trwJOIN)
                    '            End If
                    '        Next trwJOIN
                    '    End If 'sdpXLAT
                    'End Function 'Link_Table
                End Class 'rUserBowl

                Public Class sUserBowl
                    Inherits TablePKEnum(Of enmUB, enmUN, rUserBowl)

                    'Public Sub Cboard_CmdlineAudit()
                    '    If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    '        Dim strAUDIT = Me.ToString(True)
                    '        Dim ins_msg = Mx.Have.MessageBox.Ins(
                    '            New Mx.Have.rMessageBox().
                    '                vt(enmMB.title, Me.SelKey(enmUN.app_name).v(enmUB.contents)).
                    '                vt(enmMB.text, strAUDIT),
                    '            MsgBoxStyle.OkCancel
                    '            )
                    '        If ins_msg.vUserResponse = MsgBoxResult.Ok Then
                    '            Mx.Have.Clipboard.Ins(
                    '                New Mx.Have.rClipboard().
                    '                vt(enmCB.text, strAUDIT)
                    '                )
                    '        End If
                    '    End If
                    'End Sub 'Cboard_CmdlineAudit

                    'Public Function InsFrom_Application() As rUserBowl
                    '    Dim ret = New rUserBowl
                    '    InsFrom_Application = ret
                    '    'Me.InsKey(enmUN.app_name, New MxText.FileName().d(Mx.Class1.SourcePath).FileGroup)
                    '    'Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                    '    'Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                    '    Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                    '    Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                    '    Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                    '    For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    '        Me.Ins(
                    '            New Have.rUserBowl().
                    '            vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                    '            vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                    '            )
                    '    Next
                    'End Function 'InsFrom_Application

                    'Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    '    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                    'End Function
                End Class 'sUserBowl
            End Class 'Have
        End Class 'prv_sample
    End Class 'Have.prv_sample
End Namespace 'Mx

VBNetProject\VBNetScript

<<ext "VBNetScript.EXE">>

<<ext "VBNetScript.SLN">>

VBNS Project

<<glbl_article_list>>

VBNS Project\~MockTestReport

```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
dbUserInputMock.vb
ScriptRun.vb
subs.vb
RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx2

Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock

    Public Class Want
        Public Shared Function CompileCode_Report_errhnd(ur_commandline_text As String) As Mx.Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Mx.Strapd()
            CompileCode_Report_errhnd = stpRET
            stpRET.d("RED").dLine()
            Dim objERR_LIST = New Mx.ErrListBase : Try
                Call Assistant.CompileCode_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'CompileCode_Report_errhnd
    End Class 'Want

    Public Class Assistant
        Public Shared Sub CompileCode_Report(ur_ret As Mx.Strap)
            Dim windowsfs_env = Have.WindowsFS
            Dim userbowl_cart = Have.UserBowl
            Dim appfolder_bowlname = enmUN.app_folder
            Dim mocktest_cart = Have.MockTest
            Dim intRECS_INSERTED = mocktest_cart.Apply(userbowl_cart, appfolder_bowlname, windowsfs_env)
            Dim intRECS_TESTED = mocktest_cart.Apply(windowsfs_env)

            Dim from_messagebox_bowlname = userbowl_cart.Apply(mocktest_cart, ur_ret)
        End Sub 'CompileCode_Report
    End Class 'Assistant

    Partial Public Class Have
        Partial Public Class sMockTest
            Public Function Apply(ur_userbowl_cart As Have.sUserBowl, ur_appfolder_bowlname As enmUN, ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_ADDED = 0
                Dim strSEARCH_TEST_NAME = "MockTest\*.mock_commandline.txt"
                Dim strSEARCH_RESULT_NAME = ".mock_expect.txt"
                Dim flnAPP_FOLDER = Mx.FileNamed.d(ur_userbowl_cart.SelKey(ur_appfolder_bowlname).Contents)
				Dim fltSEARCH_MOCK_COMMANDLINE = flnAPP_FOLDER.gCopy.d(strSEARCH_TEST_NAME)
                For Each strPATH In ur_windowsfs_env.GetFiles(fltSEARCH_MOCK_COMMANDLINE.gParentDir, fltSEARCH_MOCK_COMMANDLINE.Name, System.IO.SearchOption.TopDirectoryOnly)
					
                    Dim flnTEST_FILE_PATH = Mx.FileNamed.d(strPATH)
                    Dim rowMOCK_TEST = Me.InsKey(strPATH)
                    retREC_ADDED += 1
                    Dim flnTEST_CODE_PATH = flnTEST_FILE_PATH.gParentDir.d(Mx.FileNamed().d(flnTEST_FILE_PATH.FileGroup).FileGroup)
                    For Each strTEST_CODE_PATH In ur_windowsfs_env.GetFiles(flnTEST_CODE_PATH.gParentDir, flnTEST_CODE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.test_code_file, strTEST_CODE_PATH)
                        Exit For
                    Next
					
                    Dim flnRESULT_FILE_PATH = flnTEST_CODE_PATH.gCopy.dAppendEXT(strSEARCH_RESULT_NAME)
                    For Each strEXPECTED_RESULT_PATH In ur_windowsfs_env.GetFiles(flnRESULT_FILE_PATH.gParentDir, flnRESULT_FILE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.mock_expect_file, strEXPECTED_RESULT_PATH)
                        Exit For
                    Next
                Next strPATH

                Apply = retREC_ADDED
            End Function 'Apply ur_userbowl_cart

            Public Function Apply(ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_TESTED = 0
                For Each rowMOCK_TEST In Me.SelAll
                    retREC_TESTED += 1
                    If Mx.HasText(rowMOCK_TEST.v(enmMT.test_code_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Test Code File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    ElseIf Mx.HasText(rowMOCK_TEST.v(enmMT.mock_expect_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Mock Expect File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    Else
						Dim strTEST_CODEFILE_PATH = rowMOCK_TEST.v(enmMT.test_code_file)
                        Dim strCOMMANDLINE_PARMS = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_commandline_file))
                        Dim strEXPECTED_RESULT = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_expect_file))

                        Dim mockTextBox = New Mock.TextBox
                        Dim mockForm = New Mock.Form
                        Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
                        Dim stpTEST_COMMANDLINE = Mx.Strapd().d("vbnetscript.exe").dS("/path=").dSprtr(Mx.qs, strTEST_CODEFILE_PATH).d(Mx.qs).dS(strCOMMANDLINE_PARMS)
                        Call Mx.Want.Compile_And_Run_Script_errhnd(mockUserInput, stpTEST_COMMANDLINE)
                        Dim strFOUND_RESULT = mockTextBox.Text
                        If strFOUND_RESULT = strEXPECTED_RESULT Then
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "1")
						
                        Else
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
                            rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`"))
                        End If 'strFOUND_RESULT
                    End If
                Next rowMOCK_TEST

                Apply = retREC_TESTED
            End Function 'Apply ur_windowsfs_env
        End Class 'sMockTest

        Partial Public Class sUserBowl
            Public Function Apply(ur_mocktest_cart As Have.sMockTest, ur_ret As Mx.Strap) As enmUN
                Dim retUN = enmUN.from_messagebox
                Apply = retUN

                Dim intTEST_PASS = 0
                Dim intTEST_FAIL = 0
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "1" Then
                        intTEST_PASS += 1

                    Else
                        intTEST_FAIL += 1
                    End If
                Next rowMOCK_TEST

                If intTEST_PASS = ur_mocktest_cart.SelAll.Count Then
                    ur_ret.Clear().dLine("GREEN").dLine()
                End If

                ur_ret.dLine(intTEST_PASS.ToString).dS("Tests passed")
                ur_ret.dLine(intTEST_FAIL.ToString).dS("Tests failed")
				ur_ret.dLine()
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "0" Then
                        ur_ret.dLine(rowMOCK_TEST.v(enmMT.test_result_text))
						ur_ret.dLine()
                    End If
                Next rowMOCK_TEST
            End Function 'Apply ur_messagebox_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblMockTest As sMockTest
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblMockTest = New sMockTest
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmMT
        Inherits Mx.bitBASE
        Public Shared mock_commandline_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared mock_expect_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_code_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_result_text As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_pass_count As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
    End Class 'enmMT

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function MockTest() As sMockTest
            Call Have.Connect()
            MockTest = Have.tblMockTest
        End Function

        Public Class rMockTest
            Inherits Mx.TRow(Of enmMT)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmMT, ur_val As String) As rMockTest
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rMockTest

        Public Class sMockTest
            Inherits Mx.TablePKStr(Of enmMT, rMockTest)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                MyBase.New(1)
            End Sub
        End Class
    End Class 'enmMT

    Public Class enmUB
        Inherits Mx.bitBASE
        Public Shared bowl_name As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits Mx.bitBASE
        Public Shared app_folder As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits Mx.bitBASE
        Public Shared Ok As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits Mx.TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = Mx.AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If Mx.HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = Mx.MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = Mx.qs & Have.CmdLineText.Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                Me.SelKey(enmUN.cmdline_table).Contents = Mx.qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx2

VBNS Project\~VersionUpd

```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.FileUpdate_Report_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.FileUpdate_Report_errhnd
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub FileUpdate_Report(ur_ret As Strap)
            Dim userbowl_cart = Have.UserBowl
            Dim appname_bowlname = enmUN.app_name
            Dim appfolder_bowlname = enmUN.app_folder
            Dim windows_msgbox_env = Have.WindowsMsgBox
            Dim windows_fs_env = Have.WindowsFS
            Dim tempfile_cart = Have.TempFile
            tempfile_cart.Apply(userbowl_cart.SelKey(appfolder_bowlname), windows_fs_env)
            Dim report_output_bowlname = userbowl_cart.Apply(tempfile_cart)
            Dim from_messagebox_bowlname = userbowl_cart.Apply(
                ur_userbowl_text:=userbowl_cart.SelKey(report_output_bowlname),
                ur_userbowl_appname:=userbowl_cart.SelKey(appname_bowlname),
                ur_messagebox_env:=windows_msgbox_env
                )
        End Sub 'FileUpdate_Report

        Public Shared Function FileUpdate_Report_errhnd() As Strap
            Dim stpRET = Strapd()
            FileUpdate_Report_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call FileUpdate_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'FileUpdate_Report_errhnd
    End Class 'Want

    Partial Public Class Have
        Partial Class sTempFile
            Public Sub Apply(ur_app_folder As Have.rUserBowl, ur_windows_fs_env As Have.glblWindowsFS)
                Dim flnROOT_FOLDER = FileNamed().d(ur_app_folder.v(enmUB.contents))
                Dim flnMY_PROJECT = flnROOT_FOLDER.gCopy.d("My Project")
                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnROOT_FOLDER, "*.vbproj", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.VBProj, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.VBProj).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.VBProj.name).dS("file in folder"))
                End If

                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnMY_PROJECT, "AssemblyInfo.vb", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.AssemblyInfo, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.AssemblyInfo).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.AssemblyInfo.name).dS("file in folder"))
                End If
            End Sub 'Apply(ur_app_folder
        End Class 'sTempFile

        Partial Public Class sUserBowl
            Public Function Apply(ur_userbowl_text As Have.rUserBowl, ur_userbowl_appname As Have.rUserBowl, ur_messagebox_env As Have.glblWindowsMsgBox) As bitBASE
                Dim retUN = enmUN.from_messagebox
                Apply = retUN
                Dim enrUSER_INPUT = ur_messagebox_env.GetResult(
                    ur_message:=ur_userbowl_text.v(enmUB.contents),
                    ur_title:=ur_userbowl_appname.v(enmUB.contents),
                    ur_style:=MsgBoxStyle.OkOnly
                    )

                If enrUSER_INPUT = MsgBoxResult.Ok Then
                    Me.InsKey(retUN, enmUR.Ok)
                End If
            End Function 'Apply ur_messagebox_cart

            Public Function Apply(ur_tempfile_cart As Have.sTempFile) As enmUN
                Dim retUN = enmUN.report_output
                Apply = retUN
                Dim strDATE = Today.ToString("yyyy.MM.dd")
                Dim intCURRENT = 1

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.VBProj.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<ApplicationRevision>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationRevision>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, InStr(strPARSE, "<") - 1)
                                    If System.Int32.TryParse(strPARSE, intCURRENT) Then
                                        intCURRENT += 1
                                    End If

                                ElseIf StartingWithText(strLINE.TrimStart, "<ApplicationVersion>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationVersion>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, 10)
                                    If AreEqual(strPARSE, strDATE) = False Then
                                        intCURRENT = 1
                                    End If 'strPARSE

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationRevision>")
                                    stmSECOND.Write(intCURRENT)
                                    stmSECOND.WriteLine("</ApplicationRevision>")

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationVersion>")
                                    stmSECOND.Write(Strapd().d(strDATE).d(intCURRENT.ToString("00")).d(".%2a"))
                                    stmSECOND.WriteLine("</ApplicationVersion>")

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.AssemblyInfo.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyVersion(") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyVersion").d("(").d(qs).d(Today.ToString("yyyy.MM.dd")).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                ElseIf StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyFileVersion") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyFileVersion").d("(").d(qs).d(strDATE).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                Me.InsKey(retUN, Strapd().d("Files updated:").dS(ur_tempfile_cart.SelAll.Count.ToString))
            End Function 'Apply ur_tempfield_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblTempFile As sTempFile
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblTempFile = New sTempFile
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmTF
        Inherits bitBASE
        Public Shared file_search As enmTF = TRow(Of enmTF).glbl.NewBitBase()
        Public Shared filename As enmTF = TRow(Of enmTF).glbl.NewBitBase()
    End Class

    Public Class enmTN
        Inherits bitBASE
        Public Shared AssemblyInfo As enmTN = TRow(Of enmTN).glbl.NewBitBase()
        Public Shared VBProj As enmTN = TRow(Of enmTN).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function TempFile() As sTempFile
            Call Have.Connect()
            TempFile = Have.tblTempFile
        End Function

        Public Class rTempFile
            Inherits TRow(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmTF, ur_val As String) As rTempFile
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rTempFile

        Public Class sTempFile
            Private ttb As Objlist(Of rTempFile)
            Private PK As Objlist(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rTempFile)
                Me.PK = New Objlist(Of enmTF)
                Me.PK.Add(enmTF.file_search)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Del(ur_col As enmTF, ur_val As String)
                For ROWCTR = Me.ttb.Count To 1 Step -1
                    If AreEqual(Me.ttb.tr_b1(ROWCTR).v(ur_col), ur_val) Then
                        Me.ttb.RemoveAt(b0(ROWCTR))
                    End If
                Next ROWCTR
            End Sub 'Del

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Ins(ur_from As rTempFile)
                Dim ttbSEL = Me
                Dim stpPK_LIST = Strapd()
                For Each keyPK In Me.PK
                    Dim strCUR_KEY = ur_from.v(keyPK)
                    If stpPK_LIST.Length > 0 Then stpPK_LIST.d(", ")
                    stpPK_LIST.d(strCUR_KEY)
                    If HasText(strCUR_KEY) = False Then
                        Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("PK value must have data:").dS(keyPK.name))
                    Else
                        ttbSEL = ttbSEL.Sel(keyPK, ur_from.v(keyPK))
                    End If
                Next keyPK

                If ttbSEL.SelAll.Count > 0 Then
                    Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("must have unique PK values:").dS(stpPK_LIST.ToString))
                Else
                    Me.ttb.Add(ur_from)
                End If
            End Sub 'Ins

            <System.Diagnostics.DebuggerHidden()>
            Public Sub InsKey(ur_key As enmTN, ur_val As String)
                Dim ret = Me.SelKey(ur_key)
                If HasText(ret.v(enmTF.filename)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmTF.filename, ur_val)
                End If
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmTF, ur_value As String) As sTempFile
                Dim retUB = New sTempFile
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rTempFile)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmTN) As rTempFile
                Dim ret As rTempFile = Nothing
                Dim strKEY = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmTF.file_search), strKEY) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rTempFile
                    Me.ttb.Add(
                        ret.
                        vt(enmTF.file_search, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sTempFile
    End Class 'TF

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Private ttb As Objlist(Of rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rUserBowl)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rUserBowl) As rUserBowl
                Ins = ur_from
                Me.ttb.Add(ur_from)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As String) As rUserBowl
                Dim ret = Me.SelKey(ur_key)
                InsKey = ret
                If HasText(ret.v(enmUB.contents)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmUB.contents, ur_val)
                End If
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As enmUR) As rUserBowl
                InsKey = Me.InsKey(ur_key, ur_val.name)
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.InsKey(enmUN.app_name, FileNamed().d(Mx.Class1.SourcePath).FileGroup)
                Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmUB, ur_value As String) As sUserBowl
                Dim retUB = New sUserBowl
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rUserBowl)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmUN) As rUserBowl
                Dim ret As rUserBowl = Nothing
                Dim strUN = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmUB.bowl_name), strUN) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rUserBowl
                    Me.ttb.Add(
                        ret.
                        vt(enmUB.bowl_name, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

VBNS Project\Roman to Decimal

<<ext "Roman to Decimal ZIP">>

* Asks for a Roman Numeral
* Returns a decimal number or an error with the invalid sequence and the broken rule

```
Namespace Mx
	Public Class mb
		Public Shared FirstExec As Object
		Public Shared uinput As Microsoft.VisualBasic.MsgBoxResult

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub ask(ur_text As String)
			Call prv.Connect()
			If mb.uinput <> MsgBoxResult.Cancel Then
				mb.uinput = Microsoft.VisualBasic.MsgBox(ur_text, MsgBoxStyle.OkCancel, "")
			End If
		End Sub 'ask

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Function GetText(ur_question As String) As String
			GetText = Microsoft.VisualBasic.InputBox(ur_question, "")
		End Function

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub reset()
			Call prv.Connect()
			mb.uinput = MsgBoxResult.Ok
		End Sub

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Sub Connect()
				If mb.FirstExec Is Nothing Then
					mb.uinput = MsgBoxResult.Ok
					mb.FirstExec = "done"
				End If
			End Sub 'Connect
		End Class 'prv
	End Class 'mb

	Public Class UserAction
		Public Shared Function Roman_Numeral_Conversion_Report() As String
			mb.reset()
			Dim strRET_MSG = ""
			Dim strNUMERAL = mb.GetText("Enter a Roman numeral")
			Dim strDECIMAL = Assistant.Roman_Numeral_Conversion_Result(strNUMERAL)
			strRET_MSG = strNUMERAL & " rom. = " & strDECIMAL & " dec."
			Roman_Numeral_Conversion_Report = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Report
	End Class 'UserAction

	Public Class Assistant
		Public Shared Function Roman_Numeral_Conversion_Result(ur_numeral As String) As String
			Dim strRET_MSG = ""
			Dim rmnNUMERAL = New Mx.glblRomanNumeral(ur_numeral)
			strRET_MSG = rmnNUMERAL.Validation_Message
			If strRET_MSG = "" Then
				strRET_MSG = rmnNUMERAL.ToInteger.ToString
			End If

			Roman_Numeral_Conversion_Result = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Result
	End Class 'Assistant

	Public Class glblRomanNumeral
		Private strpNumeral As String

		Private Enum enmLH
			low_or_high_number
			high_number
			low_number
		End Enum

		Private siaSymbol_Size As Mx.sia

		<System.Diagnostics.DebuggerHidden()>
		Public Sub New(ur_numeral As String)
			Me.strpNumeral = ur_numeral.Trim.ToUpper
			Me.siaSymbol_Size = prv.glbl_Symbol_Sizes()
		End Sub

		Public ReadOnly Property Numeral As String
			<System.Diagnostics.DebuggerHidden()>
			Get
				Numeral = Me.strpNumeral
			End Get
		End Property 'Numeral

		Public Function IsValid() As Boolean
			IsValid = (Me.Validation_Message = "")
		End Function

		Public Function Validation_Message() As String
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_Valid

			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, "", symbol_size_table)

			Validation_Message = clrRET_STATE.strNOTICE_MSG
		End Function 'Validation_Message

		Public Function ToInteger() As Integer
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_State
			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				Dim clPREV_STATE = clrRET_STATE
				clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, "", symbol_size_table)

			ToInteger = clrRET_STATE.intRET_NUM
		End Function 'ToInteger

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function glbl_Symbol_Sizes() As Mx.sia
				Dim retSIA = New Mx.sia
				glbl_Symbol_Sizes = retSIA
				retSIA.Add("I", 1)
				retSIA.Add("V", 5)
				retSIA.Add("X", 10)
				retSIA.Add("L", 50)
				retSIA.Add("C", 100)
				retSIA.Add("D", 500)
				retSIA.Add("M", 1000)

				glbl_Symbol_Sizes = retSIA
			End Function 'glbl_Symbol_Sizes

			Public Class Loop_State
				Public enrSTATE As enmLH
				Public strLOW_OR_HIGH_TEMP As String
				Public intRET_NUM As Integer

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Me.enrSTATE = enmLH.high_number
					Me.strLOW_OR_HIGH_TEMP = ""
					Me.intRET_NUM = 0
				End Sub 'New
			End Class 'Loop_State

			Public Class Loop_Valid
				Public strVAL_FOUR As String
				Public strVAL_THREE As String
				Public strVAL_TWO As String
				Public strVAL_ONE As String
				Public intVAL_FOUR As Integer
				Public intVAL_THREE As Integer
				Public intVAL_TWO As Integer
				Public intVAL_ONE As Integer
				Public strNOTICE_MSG As String

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Call prvLoop_Valid.Reset_Symobls(Me)
					Me.strNOTICE_MSG = ""
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia)
					Me.strVAL_FOUR = ur_state.strVAL_THREE
					Me.intVAL_FOUR = ur_state.intVAL_THREE
					Me.strVAL_THREE = ur_state.strVAL_TWO
					Me.intVAL_THREE = ur_state.intVAL_TWO
					Me.strVAL_TWO = ur_state.strVAL_ONE
					Me.intVAL_TWO = ur_state.intVAL_ONE
					Me.strVAL_ONE = ur_new_symbol
					Me.intVAL_ONE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
					Me.strNOTICE_MSG = ur_state.strNOTICE_MSG
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub Assign_NoticeMsg(ur_message As String)
					If strNOTICE_MSG <> "" Then
						strNOTICE_MSG &= vbCrLf & vbCrLf
					End If

					strNOTICE_MSG &= ur_message
					Call prvLoop_Valid.Reset_Symobls(Me)
				End Sub 'Assign_NoticeMsg

				Private Class prvLoop_Valid
					Public Shared Sub Reset_Symobls(ur_state As prv.Loop_Valid)
						ur_state.strVAL_FOUR = ""
						ur_state.intVAL_FOUR = 0
						ur_state.strVAL_THREE = ""
						ur_state.intVAL_THREE = 0
						ur_state.strVAL_TWO = ""
						ur_state.intVAL_TWO = 0
						ur_state.strVAL_ONE = ""
						ur_state.intVAL_ONE = 0
					End Sub 'Reset_Symobls
				End Class 'prv
			End Class 'Loop_Valid

			Public Shared Function Loop_Return_Valid(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_Valid
				Dim retSTATE = New prv.Loop_Valid(ur_state, ur_new_symbol, ur_symbol_size)
				Loop_Return_Valid = retSTATE
				If retSTATE.strVAL_ONE <> "" Then
					If retSTATE.intVAL_ONE = 0 Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							If strLIST <> "" Then
								strLIST &= ", "
							End If

							strLIST &= strENTRY
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used in Roman numerals.")

					ElseIf retSTATE.strVAL_FOUR = retSTATE.strVAL_THREE AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_TWO AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_ONE Then
						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_FOUR & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & ur_new_symbol & "] is not valid: A single symbol may not be repeated more than three times.")

					ElseIf retSTATE.strVAL_TWO = retSTATE.strVAL_ONE AndAlso
					  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
							If Left(strENTRY_VAL, 1) = "1" Then
								If strLIST <> "" Then
									strLIST &= ", "
								End If

								strLIST &= strENTRY
							End If
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be repeated.")

					ElseIf retSTATE.strVAL_TWO <> "" Then
						If retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
							Dim strLIST = ""
							For Each strENTRY In ur_symbol_size.Keys
								Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
								If Left(strENTRY_VAL, 1) = "1" Then
									If strLIST <> "" Then
										strLIST &= ", "
									End If

									strLIST &= strENTRY
								End If
							Next strENTRY

							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used as the lower symbol followed by a higher symbol.")

						ElseIf retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  retSTATE.intVAL_ONE <> retSTATE.intVAL_TWO * 10 Then
							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: The lower symbol must be ten times less value than the following higher symbol.")

						ElseIf retSTATE.strVAL_THREE <> "" Then
							If retSTATE.intVAL_TWO > retSTATE.intVAL_ONE AndAlso
							  retSTATE.intVAL_ONE >= retSTATE.intVAL_THREE Then
								retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: A lower symbol followed by higher symbol must be followed by lower symbol than the first of the series.")
							End If
						End If 'strVAL_THREE
					End If 'strVAL_TWO
				End If 'strVAL_ONE
			End Function 'Loop_Return_Valid

			Public Shared Function Loop_Return_State(ur_state As prv.Loop_State, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_State
				Dim retSTATE = New prv.Loop_State
				Loop_Return_State = retSTATE

				Dim intNEW_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
				Dim intLOW_OR_HIGH_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_state.strLOW_OR_HIGH_TEMP)
				If ur_state.strLOW_OR_HIGH_TEMP = "" Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM
					retSTATE.enrSTATE = enmLH.low_or_high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol

				ElseIf intNEW_VALUE > intLOW_OR_HIGH_VALUE Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intNEW_VALUE - intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ""

				Else
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.low_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol
				End If
			End Function 'Loop_Return_State

			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function Numeral_To_Int(ur_symbol_size As Mx.sia, ur_numeral As String) As Integer
				Numeral_To_Int = 0
				If ur_symbol_size.ContainsKey(ur_numeral) Then
					Numeral_To_Int = ur_symbol_size.Item(ur_numeral)
				End If
			End Function 'Numeral_To_Int
		End Class 'prv
	End Class 'glblRomanNumeral

	Public Class sia
		Inherits System.Collections.Generic.Dictionary(Of String, Integer)
	End Class
End Namespace 'Mx

VBNS Project\Wiki_Move_HTM

<<ext "Wiki Move HTM">>

```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
End Function '2021m01d03
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Const strLIT_WIKI_MOVE_5_SEC = "Wiki Move 5-Sec"
        Const strvLIT_USER_PROFILE_DOWNLOADS = "%USERPROFILE%\downloads"
        Const strLIT_STAR_DOT_HTM = "WikiMove_*-stamp-*.htm"
        Const strLIT_STAR_DOT_HTML = "WikiMove_*-stamp-*.html"
        Const strLIT_STAR_DOT_CARDTXT = "WikiMove_*-stamp-*.card*.txt"

        Public Shared Sub UITimer_to_Poll_FileDir_And_Move(ur_ret As Strap)
            ur_ret.d("QUIT")
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            Dim strUI_FORM_TITLE = strLIT_WIKI_MOVE_5_SEC
            userbowl_cart.SelKey(uiform_title_bowlname).Contents = strUI_FORM_TITLE
            userbowl_cart.SelKey(enmUN.poll_folder).Contents = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)
            If glbl.gDiagnostics.IsRunningWindow(strUI_FORM_TITLE) Then
                glbl.gInteraction.AppActivate(strUI_FORM_TITLE)

            Else
                Dim objFORM = New Mx.WikiMove_Form()
                objFORM.Text = userbowl_cart.SelKey(enmUN.uiform_title).v(enmUB.contents)
                Call objFORM.Display_FolderList()
                objFORM.tmrFIVE_SEC.Start()
                Dim strNEW_DATA_FOLDER = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)

                'System.Windows.Forms.Application.Run(objFORM) only works from a command line program with no forms open. VBNetScript already has a form open.
                Call objFORM.ShowDialog()
            End If 'gDiagnostics
        End Sub 'UITimer_to_Poll_FileDir_And_Move

        Public Shared Function UITimer_to_Poll_FileDir_And_Move_errhnd(ur_commandline_text As String) As Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Strapd()
            UITimer_to_Poll_FileDir_And_Move_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call UITimer_to_Poll_FileDir_And_Move(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'UITimer_to_Poll_FileDir_And_Move_errhnd

        Public Shared Sub Poll_FileDir_And_Move(ur_ui_form As WikiMove_Form)
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            Dim windows_fs_cart = Have.WindowsFS
            Dim filemove_cart = Have.FileMove
            Call ur_ui_form.Display_FolderList()
            filemove_cart.DelAll()
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTM)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTML)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_CARDTXT)
            filemove_cart.Move_Files()
            Dim report_output_bowlname = userbowl_cart.Apply(filemove_cart)
            Dim strREPORT_OUTPUT = userbowl_cart.SelKey(report_output_bowlname).v(enmUB.contents)
            If HasText(strREPORT_OUTPUT) Then
                ur_ui_form.txtOUTPUT.Text = strREPORT_OUTPUT & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move

        Public Shared Sub Poll_FileDir_And_Move_errhnd(ur_ui_form As WikiMove_Form)
            Dim objERR_LIST = New ErrListBase : Try
                Call Poll_FileDir_And_Move(ur_ui_form:=ur_ui_form)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                ur_ui_form.txtOUTPUT.Text = objERR_LIST.ToString & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move_errhnd

        Public Class CombineTextOutput
            Public gText As Strap
            Public gFolderList As Sdata

            Public Sub New(ur_text As Strap, ur_folder_list As Sdata)
                Me.gText = ur_text
                Me.gFolderList = ur_folder_list
            End Sub
        End Class 'CombineTextOutput
    End Class 'sub_main

    Public Class WikiMove_Form
        Inherits System.Windows.Forms.Form

        Public tmrFIVE_SEC As System.Windows.Forms.Timer
        Public txtOUTPUT As System.Windows.Forms.TextBox
        Public intSHOW_FORM As Integer

        Public Sub New()
            Me.intSHOW_FORM = 1

            Me.Name = "Wiki_Move"
            Me.Size = New System.Drawing.Size(400, 400)
            Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen

            Me.txtOUTPUT = New System.Windows.Forms.TextBox()
            Me.txtOUTPUT.Name = "txtOUTPUT"
            Me.txtOUTPUT.Multiline = True
            Me.txtOUTPUT.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
            Me.txtOUTPUT.Dock = System.Windows.Forms.DockStyle.Fill
            Me.Controls.Add(Me.txtOUTPUT)

            Me.tmrFIVE_SEC = New System.Windows.Forms.Timer()
            Me.tmrFIVE_SEC.Interval = 50
            AddHandler Me.tmrFIVE_SEC.Tick, AddressOf Timer1_Tick
        End Sub 'New

        Sub Display_FolderList()
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            If HasText(Me.txtOUTPUT.Text) = False Then
                Me.txtOUTPUT.Text = Strapd().dLine("Listening:").dS(userbowl_cart.SelKey(pollfolder_bowlname).v(enmUB.contents)).dLine().d(Me.txtOUTPUT.Text)
            End If
        End Sub 'Display_FolderList

        Sub Look_For_Files()
            Call Mx.Want.Poll_FileDir_And_Move_errhnd(Me)
        End Sub

        Sub Show_Saved()
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            If Me.intSHOW_FORM = 1 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Normal
                Call AppActivate(userbowl_cart.SelKey(uiform_title_bowlname).v(enmUB.contents))
                Me.tmrFIVE_SEC.Interval = 800
                Me.intSHOW_FORM = 2

            ElseIf Me.intSHOW_FORM = 2 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Minimized
                Me.intSHOW_FORM = 0

            ElseIf Me.intSHOW_FORM = 0 Then
                If Me.WindowState <> System.Windows.Forms.FormWindowState.Minimized Then
                    Me.intSHOW_FORM = 6
                End If

            Else
                Me.intSHOW_FORM -= 1
            End If
        End Sub 'Show_Saved

        Sub Timer1_Tick(sender As Object, e As System.EventArgs)
            Me.tmrFIVE_SEC.Stop()
            Me.tmrFIVE_SEC.Interval = 5000
            Call Look_For_Files()
            Call Show_Saved()
            Me.tmrFIVE_SEC.Start()
        End Sub 'Timer1_Tick
    End Class 'WikiMove_Form




    Public Class Have
        Partial Class sFileMove
            Public Sub Apply(ur_windows_fs_cart As Have.glblWindowsFS, ur_userbowl_cart As Have.sUserBowl, ur_poll_folder_bowlname As enmUN, ur_filespec As String)
                Dim strPOLL_FOLDER = ur_userbowl_cart.SelKey(ur_poll_folder_bowlname).Contents
                For Each strFILE_PATH In ur_windows_fs_cart.GetFiles(strPOLL_FOLDER, ur_filespec, System.IO.SearchOption.TopDirectoryOnly)
                    Dim flnFILE_NAME = FileNamed().d(strFILE_PATH)
                    Dim sdaEXT_LIST = flnFILE_NAME.ExtList
                    Dim strDEST_PATH_ENCODED_IN_NAME = flnFILE_NAME.Name.Substring("WikiMove_".Length)
                    Dim strDEST_PATH = strDEST_PATH_ENCODED_IN_NAME.Replace("-colon-", ":").Replace("-fslash-", "\")
                    Dim intSTAMP = InStr(strDEST_PATH, "-stamp-")
                    strDEST_PATH = Left(strDEST_PATH, intSTAMP - 1)
                    Dim strEXT = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count))
                    If sdaEXT_LIST.Count > 1 Then
                        Dim strEXT2 = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count - 1))
                        If AreEqual(strEXT, ".txt") AndAlso
                          StartingWithText(strEXT2, ".card") Then
                            strEXT = ".card.txt"
                        End If
                    End If 'sdaEXT_LIST

                    strDEST_PATH &= strEXT
                    Me.Ins(
                        New rFileMove().
                        vt(enmFM.src_file_path, strFILE_PATH).
                        vt(enmFM.dest_file_path, strDEST_PATH)
                        )
                Next strFILE_PATH
            End Sub 'Apply ur_windows_fs_cart

            Public Sub Move_Files()
                Dim lstLEN = New System.Collections.Generic.List(Of Integer)
                For Each rowFILE In Me.SelAll
                    Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                    Dim intLEN = strFILE_PATH.Length
                    If lstLEN.Contains(intLEN) = False Then
                        lstLEN.Add(intLEN)
                    End If
                Next rowFILE

                Call lstLEN.Sort()
                For Each intLEN In lstLEN
                    For Each rowFILE In Me.SelAll
                        Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                        If strFILE_PATH.Length = intLEN Then
                            Dim strDEST_PATH = rowFILE.v(enmFM.dest_file_path)
                            glbl.gWindowsFS.Move(strFILE_PATH, strFILE_PATH & ".TDLY")
                            glbl.gWindowsFS.Delete(strDEST_PATH)
                            glbl.gWindowsFS.Move(strFILE_PATH & ".TDLY", strDEST_PATH)
                        End If 'strFILE_PATH
                    Next rowFILE
                Next intLEN
            End Sub 'Move_Files
        End Class 'sFileMove

        Partial Class sUserBowl
            Public Function Apply(ur_filemove_cart As sFileMove) As enmUN.zreport_output
                Dim retKEY = enmUN.report_output
                Apply = retKEY
                Dim stpREPORT = Strapd()
                For Each rowFILE In ur_filemove_cart.SelAll
                    stpREPORT.dLine(Now.ToString("tt hh:mm:ss")).d(":").dS(rowFILE.v(enmFM.dest_file_path))
                Next rowFILE

                Me.SelKey(retKEY).v(enmUB.contents) = stpREPORT
            End Function 'Apply(ur_filemove_cart
        End Class 'sUserBowl
    End Class 'Have



    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblFileMove As sFileMove
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblFileMove = New sFileMove
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmFM
        Inherits bitBASE
        Public Shared src_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
        Public Shared dest_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
    End Class

    Partial Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function FileMove() As sFileMove
            Call Have.Connect()
            FileMove = Have.tblFileMove
        End Function

        Public Class rFileMove
            Inherits TRow(Of enmFM)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmFM, ur_val As String) As rFileMove
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rFileMove

        Public Class sFileMove
            Private ttb As Objlist(Of rFileMove)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rFileMove)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub DelAll()
                Me.ttb.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rFileMove) As rFileMove
                Ins = ur_from
                Dim ttbSEL = Me
                Me.ttb.Add(ur_from)
            End Function 'Ins

            Public ReadOnly Property SelAll() As Objlist(Of rFileMove)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sFileMove
    End Class 'Have

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared poll_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared uiform_title As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function 'UserBowl

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = Have.WindowsMsgBox.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(strAUDIT)
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

View All Cards

<$list filter="[all[tiddlers]!tag[EXTLINK]!tag[IMG]!tag[INDEX]!tag[MCR]!tag[META]!has[draft.of]!is[image]!is[tag]!is[system]has[tags]!prefix[undefined]sort[title]]">
<hr>
<h2><$link to=<<currentTiddler>> /></h2>
{{||$:/core/ui/ViewTemplate/tags}}
<$transclude mode="block"/>
</$list>

View All Code

<$list variable=cur_card_pk filter="[!has[draft.of]!prefix[undefined]!prefix[$]] [prefix[$]!has[draft.of]has[tags]] +[sort[title]]">
<hr>
<h2><$link to=<<cur_card_pk>> /></h2>
<$list variable=cur_card_tags filter="[<cur_card_pk>tags[]]">
<<cur_card_tags>> 
</$list><!--cur_card_text-->
<$list variable=cur_card_text filter="[<cur_card_pk>get[text]]">
<$codeblock code=<<cur_card_text>> />
</$list><!--cur_card_text-->
</$list><!--cur_card_pk-->

WindowsCLI

<<glbl_article_list>>

WindowsCLI\Batch Replacement Parameters

"""
User Replacement Text = UrProgram

[Example.cmd file]
- SET CUR_DIR=%~dp0
- "%CUR_DIR%UrProgram.exe"

WindowsCLI\Command line hide Errors

"""
[Windows CLI]
- [Turn off standard messages being echoed to the console]
- `@@ECHO OFF`

[https://docs.microsoft.com/en-us/troubleshoot/cpp/redirecting-error-command-prompt]
- To redirect the error message to NUL, use the following command:
"""

```
dir file.xxx 2> nul
```

"""
- You can print the errors and standard output to a single file by using the &1 command to redirect the output for STDERR to STDOUT and then sending the output from STDOUT to a file:
"""

```
dir file.xxx 1> output.msg 2>&1
```

WindowsCLI\Command list

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands

"""

Prerequisites
The information that is contained in this topic applies to:Windows Server 2019

Windows Server (Semi-Annual Channel)

Windows Server 2016

Windows Server 2012 R2

Windows Server 2012

Windows Server 2008 R2

Windows Server 2008

Windows 10

Windows 8.1Command shell overview
The Command shell was the first shell built into Windows to automate routine tasks, like user account management or nightly backups, with batch (.bat) files. With Windows Script Host you could run more sophisticated scripts in the Command shell. For more information, see
cscript
or
wscript
. You can perform operations more efficiently by using scripts than you can by using the user interface. Scripts accept all Commands that are available at the command line.

Windows has two command shells: The Command shell and
PowerShell
. Each shell is a software program that provides direct communication between you and the operating system or application, providing an environment to automate IT operations.

PowerShell was designed to extend the capabilities of the Command shell to run PowerShell commands called cmdlets. Cmdlets are similar to Windows Commands but provide a more extensible scripting language. You can run Windows Commands and PowerShell cmdlets in Powershell, but the Command shell can only run Windows Commands and not PowerShell cmdlets.

For the most robust, up-to-date Windows automation, we recommend using PowerShell instead of Windows Commands or Windows Script Host for Windows automation.

Note

You can also download and install
PowerShell Core
, the open source version of PowerShell. Caution

Incorrectly editing the registry may severely damage your system. Before making the following changes to the registry, you should back up any valued data on the computer. Note

To enable or disable file and directory name completion in the Command shell on a computer or user logon session, run
regedit.exe
and set the following
reg_DWOrd value
:

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\completionChar\reg_DWOrd

To set the
reg_DWOrd
value, use the hexadecimal value of a control character for a particular function (for example,
0 9
is Tab and
0 08
is Backspace). User-specified settings take precedence over computer settings, and command-line options take precedence over registry settings.Command-line reference A-Z
To find information about a specific Windows Command, in the following A-Z menu, click the letter that the Command starts with, and then click the Command name.

A append
arp
assoc
at
atmadm
attrib
auditpol
autochk
autoconv
autofmt
B bcdboot
bcdedit
bdehdcfg
bitsadmin
bitsadmin addfile
bitsadmin addfileset
bitsadmin addfilewithranges
bitsadmin cancel
bitsadmin complete
bitsadmin create
bitsadmin getaclflags
bitsadmin getbytestotal
bitsadmin getbytestransferred
bitsadmin getcompletiontime
bitsadmin getcreationtime
bitsadmin getdescription
bitsadmin getdisplayname
bitsadmin geterror
bitsadmin geterrorcount
bitsadmin getfilestotal
bitsadmin getfilestransferred
bitsadmin getminretrydelay
bitsadmin getmodificationtime
bitsadmin getnoprogresstimeout
bitsadmin getnotifycmdline
bitsadmin getnotifyflags
bitsadmin getnotifyinterface
bitsadmin getowner
bitsadmin get priority
bitsadmin getproxybypasslist
bitsadmin getproxylist
bitsadmin getproxyusage
bitsadmin getreplydata
bitsadmin getreplyfilename
bitsadmin getreplyprogress
bitsadmin getstate
bitsadmin gettype
bitsadmin help
bitsadmin info
bitsadmin list
bitsadmin listfiles
bitsadmin monitor
bitsadmin nowrap
bitsadmin rawreturn
bitsadmin removecredentials
bitsadmin replaceremoteprefix
bitsadmin reset
bitsadmin resume
bitsadmin setaclflag
bitsadmin setcredentials
bitsadmin setdescription
bitsadmin setdisplayname
bitsadmin setminretrydelay
bitsadmin setnoprogresstimeout
bitsadmin setnotifycmdline
bitsadmin setnotifyflags
bitsadmin setpriority
bitsadmin setproxysettings
bitsadmin setreplyfilename
bitsadmin suspend
bitsadmin takeownership
bitsadmin Transfer
bitsadmin util
bitsadmin wrap bootcfg
bootcfg addsw
bootcfg copy
bootcfg dbg1394
bootcfg debug
  bootcfg default
bootcfg delete
bootcfg ems
bootcfg query
bootcfg raw
bootcfg rmsw
bootcfg timeout break
C cacls
call
cd
certreq
certutil
change
change logon
change port
change user chcp
chdir
chglogon
chgport
chgusr
chkdsk
chkntfs
choice
cipher
cleanmgr
clip
cls
Cmd
cmdkey
cmstp
color
comp
compact
convert
copy
cprofile
cscript
D date
dcgpofix
defrag
del
dfsrmig
diantz
dir
diskcomp
diskcopy
diskpart
diskperf
diskraid
diskshadow
dispdiag
dnscmd
doskey
driverquery
E echo
edit
endlocal
erase
eventcreate
eventquery
eventtriggers
evntcmd
exit
expand
extract
F fc
find
findstr
finger
flattemp
fondue
for
forfiles
format
freedisk
fsutil
fsutil 8dot3name
 fsutil behavior
 fsutil file
fsutil fsinfo
fsutil hardlink
fsutil objectid
fsutil quota
fsutil repair
fsutil reparsepoint
fsutil resource
fsutil sparse
fsutil tiering
fsutil transaction
fsutil usn
fsutil volume
fsutil wim ftp
ftype
fveupdate
G getmac
gettype
goto
gpfixup
gpresult
gpupdate
graftabl
H help
helpctr
hostname
I icacls
if
inuse
ipconfig
ipxroute
irftp
J jetpack
K klist
ksetup
ksetup:setrealm
ksetup:mapuser
ksetup:addkdc
ksetup:delkdc
ksetup:addkpasswd
ksetup:delkpasswd
ksetup:server
ksetup:setcomputerpassword
ksetup:removerealm
ksetup:domain
ksetup:changepassword
ksetup:listrealmflags
ksetup:setrealmflags
ksetup:addrealmflags
ksetup:delrealmflags
ksetup:dumpstate
ksetup:addhosttorealmmap
ksetup:delhosttorealmmap
ksetup:setenctypeattr
ksetup:getenctypeattr
ksetup:addenctypeattr
ksetup:delenctypeattr ktmutil
ktpass
L label
lodctr
logman
logman create
logman query
logman start &124; stop
logman delete
logman update
logman import &124; export logoff
lpq
lpr
M macfile
makecab
manage-bde
manage-bde: status
manage-bde: on
manage-bde: off
manage-bde: pause
manage-bde: resume
manage-bde: lock
manage-bde: unlock
manage-bde: autounlock
manage-bde: protectors
manage-bde: tpm
manage-bde: setidentifier
manage-bde: ForceRecovery
manage-bde: changepassword
manage-bde: changepin
manage-bde: changekey
manage-bde: KeyPackage
manage-bde: upgrade
manage-bde: WipeFreeSpace mapadmin
Md
mkdir
mklink
mmc
mode
more
mount
mountvol
move
mqbkup
mqsvc
mqtgsvc
msdt
msg
msiexec
msinfo32
mstsc
N nbtstat
netcfg
netsh
netstat
Net print
nfsadmin
nfsshare
nfsstat
nlbmgr
nslookup
nslookup exit command
nslookup finger command
nslookup help
nslookup ls
nslookup lserver
nslookup root
nslookup server
nslookup set
nslookup set all
nslookup set class
nslookup set d2
nslookup set debug
nslookup set domain
nslookup set port
nslookup set querytype
nslookup set recurse
nslookup set retry
nslookup set root
nslookup set search
nslookup set srchlist
nslookup set timeout
nslookup set type
nslookup set vc
nslookup view ntbackup
ntcmdprompt
ntfrsutl
O openfiles
P pagefileconfig
path
pathping
pause
pbadmin
pentnt
perfmon
ping
pnpunattend
pnputil
popd
PowerShell
PowerShell_ise
print
prncnfg
prndrvr
prnjobs
prnmngr
prnport
prnqctl
prompt
pubprn
pushd
pushprinterconnections
Q qappsrv
qprocess
query
quser
qwinsta
R rcp
rd
rdpsign
recover
reg
reg add
reg compare
reg copy
reg delete
reg export
reg import
reg load
reg query
reg restore
reg save
reg unload regini
regsvr32
relog
rem
ren
rename
repair-bde
replace
reset session
rexec
risetup
rmdir
robocopy
route_ws2008
rpcinfo
rpcping
rsh
rundll32
rwinsta
S schtasks
scwcmd
scwcmd: analyze
scwcmd: configure
scwcmd: register
scwcmd: rollback
 scwcmd: transform
 scwcmd: view
 

secedit
secedit:analyze
secedit:configure
secedit:export
secedit:generaterollback
secedit:import
secedit:validate serverceipoptin
Servermanagercmd
serverweroptin
set
setlocal
setx
sfc
shadow
shift
showmount
shutdown
sort
start
subst
sxstrace
sysocmgr
systeminfo
T takeown
tapicfg
taskkill
tasklist
tcmsetup
telnet
tftp
time
timeout
title
tlntadmn
tpmvscmgr
tracerpt
tracert
tree
tscon
tsdiscon
tsecimp
tskill
tsprof
type
typeperf
tzutil
U unlodctr
V ver
verifier
verify
vol
vssadmin
-W waitfor
wbadmin
wbadmin enable backup
wbadmin disable backup
wbadmin start backup
wbadmin stop job
wbadmin get versions
wbadmin get items
wbadmin start recovery
wbadmin get status
wbadmin get disks
wbadmin start systemstaterecovery
wbadmin start systemstatebackup
wbadmin delete systemstatebackup
wbadmin start sysrecovery
wbadmin restore catalog
wbadmin delete catalog wdsutil
wecutil
wevtutil
where
whoami
winnt
winnt32
winpop
winrs
wmic
wscript
X xcopy

WindowsCLI\Environment Variables

!! Windows CLI Environment Variable examples

<<ext "Windows Environment Variable List">>

* Environment variable %USERPROFILE%

User-replaced value = UrUserName

!! Show the Current Directory environment variable
* [Windows CLI]
* `ECHO %CD%`
* Press enter -> `C:\UrFolderPath\UrSubfolder`

!! Navigate to the C:\Users\UrUserName folder
* [Windows CLI]
* `cd %USERPROFILE%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName`

!! Navigate to the C:\Users\UrUserName\AppData\Local\Temp folder
* `cd %TEMP%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName\AppData\Local\Temp`

!! Navigate to the C:\Users\UrUserName\AppData\Roaming folder
* `cd %APPDATA%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName\AppData\Roaming`

WindowsCLI\Unicode characters

!! Use the standard Windows ANSI Character input
<<ext "Windows Alt-Numpad Unicode">>
* Hold down Alt key, then type the Decimal sequence using only the 0-9 on the Numeric Keypad
* Note: This only works for the 255 characters in the current Windows code page

!! Enable Alt-Numeric Keypad input of Unicode Characters
* Start `RegEdit.exe`
* Navigate to`HKEY_CURRENT_USER\Control Panel\Input Method`
!!
* [New String Value]
* name = `EnableHexNumpad`
* value = `1`
!!
* [Start Menu]
* Reboot your computer
!!
* [In any Windows program]
* Turn on `Numlock`

* Hold down `Alt`-key, then type the Numeric Keypad Plus (+) key once
* Still holding down the `Alt`-key, type the hexadecimal sequence using only the letters A-F on the main keyboard and 0-9 on the Numeric Keypad
* Release the `Alt`-key -> Windows pastes the Unicode character in the current program window
* Note: This may not work for 5-digit hexadecimal codes like U+1F937

!! Use the FileFormat.Info tool Unicode Input

<<ext "FileFormat.Info UnicodeInput">>

[In any program]
* Hold down 'Alt'-key, then type the Numeric Keypad Plus (+) key -> Opens dialog box
* Note: The `U+` displayed in the window means "Enter a Unicode character number in hexadecimal format"
* Type in a hexadecimal number
* Press enter -or- Click button Send -> Closes window, types desired Unicode character in foreground window

<<ext "FileFormat.Info UnicodeInput.ZIP">>

* Note: This EXE program is able to be started from anywhere
* Note: Closing the window minimizes to the system tray as `blue circle with white lowercase letter i`

!! Display Unicode UTF-8 characters in Windows CLI

* [In some UrProgram.cmd file or Command Prompt window]
* First put the line: `@chcp 65001>nul`
* Stream UTF-8 characters from files to the Command Prompt window -> Unicode characters are shown correctly
* Note: If you do not change the code page, Unicode characters will be split into as High- and Low-ASCII characters from the current Windows code page

<<ext "WindowsCLI Unicode Support">>
* HEX input delivers a character on KeyUp of Alt; all the other ways to deliver a character happen on KeyDown; so many applications are not ready to see a character on KeyUp. (Only applicable to applications using Console-I/O API.)
* Conclusion: Many application would not react on HEX input events.
* Note: Unless your keyboard layout supports input of A LOT of characters without prefix keys, some buggy applications may skip characters when you Paste via Console’s UI
!!
* One should also keep in mind that the “alternative, ‘more capable’ consoles” for Windows are not consoles at all. They do not support Console-I/O APIs, so the programs which rely on these APIs to work would not function. (The programs which use only “File-I/O APIs to the console filehandles” would work fine, though.)
* Note: One example of such non-console is a part of MicroSoft’s Powershell. 

!! Change the default Codepage of Windows console
* [RegEdit.exe]
* Navigate to `HKEY_CURRENT_USER\Software\Microsoft\Command Processor`
!!
* [New String Value]
* Name = `Autorun`
* Value = `chcp 65001`
!!
* Actually, the trick is that the command prompt actually understands these non-english characters, just can't display them correctly
* Note: When I enter a path in the command prompt that contains some non-english chracters it is displayed as "?? ?????? ?????"
* Note:  When you submit your command (cd "??? ?????? ?????" in my case), everything is working as expected

!! <<ext "Windows Terminal Unicode Support">>
* Windows Terminal is a new, modern, fast, efficient, powerful, and productive terminal application for users of command-line tools and shells like Command Prompt, PowerShell, and WSL.

YouTube

<<glbl_article_list>>

YouTube\Captions text

!! Export closed captions text file from a YouTube video page
* Note: Android O/S will need to show the YouTube page as a Desktop Site
!!
* [Top-right icons]
* Click the three-dots menu, option Desktop site -> Reloads page
!!
* [Below video, Right-side icons]
* Click the three-dots menu, option Open Transcript -> Navigates page below video or right-side of video
* You can highlight the captions text and copy to the clipboard
* Note: You can paste the captions text into a document and save or print them

!! Find closed captions text file in YouTube video HTML content on Windows
* Type Ctrl-A to Select all text on the page
* Paste all text into a new text document
* At the top of the file, search down for "00:" to find the first line of the captions text
* Delete all text above this line
!!
* At the bottom of the file, search up for "00:" to find the last line of the captions text
* Delete all text below this line
* The remaining lines are the closed captions file

!! Find closed captions text file in YouTube video HTML content on Android O/S
* Search for "views" or [the video title] to find the end of the captions text

template Home Button

6th March 2021 at 8:06pm
$:/positivesigner/home-button $:/tags/ViewTemplate

TiddlyWiki

12th January 2021 at 10:04am
DOC

TiddlyWiki\Add Tag to All Cards

8th January 2021 at 10:44am
AssignVariable FileSystem TWCard
<$button>
<$action-setfield $tiddler="Test1" tags="COPY"/>
Reset Test1 Card's Tag list with just COPY
</$button>

<$button>
<$list variable=cur_card filter="[is[tiddler]!prefix[$:/state/]]">
<$list variable=has_tag filter="[<cur_card>tags[]count[]!match[0]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[append[COPY]]"/>
</$list>
</$list>
Append COPY tag to all Cards that already have tags
</$button>

<$button>
<$list variable=cur_card filter="[tag[COPY]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[remove[COPY]]"/>
</$list>
Remove COPY tag from all Cards
</$button>

TiddlyWiki\Backlink to HTML,HTM

8th January 2021 at 10:43am
CodeLibrary FileSystem TWCard

Title = ext TW Return

\define TW_Return(ur_url, ur_link_title)
<div style="float:right"><a href="$ur_url$"> ($ur_link_title$)</a></div>
\end
<$list filter="[<tv-config-toolbar-icons>match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="TiddlyWiki view of website" />
</$list>
</$list>
<$list filter="[<tv-config-toolbar-icons>!match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]split[.htm]join[.html]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="Static HTML view of website" />
</$list>
</$list>

TiddlyWiki\Button navigate to Card

8th January 2021 at 10:43am
FileSystem TWCard UserAction
<$vars new_code="Test1">
<$list variable=new_pk filter="[<new_code>addprefix[$:/state/popup/]]">
<$button>
<$action-sendmessage $message="tm-new-tiddler" title=<<new_pk>> tags="OneTag [[Another Tag]]" text=<<now "Today is DDth, MMM YYYY">>/>
Create Code ''<<new_code>>'' and Edit
</$button><br>

<$button>
<$action-setfield $tiddler=<<new_pk>> text="yes"/>
<$action-navigate $to=<<new_pk>>/>
Create Code ''<<new_code>>'' and Show
</$button><br>

<$link to=<<new_pk>> /><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
Close Code: ''<<new_code>>''
</$button><br>

<$list filter="[<currentTiddler>!prefix[Draft of]]" variable=strCARD_PK>
<$button>
<$list filter="[list[$:/StoryList]] -[<strCARD_PK>]" variable=strCLOSE_PK>
<$action-sendmessage $message="tm-close-tiddler" $param=<<strCLOSE_PK>>/>
</$list>
Close all other open Codes
</$button>
</$list><br>

<$button>
<$action-sendmessage $message="tm-delete-tiddler" $param=<<new_pk>> />
Delete Card: ''<<new_card>>'' with confirmation
</$button><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
<$action-deletetiddler $tiddler=<<new_pk>> />
Delete Card: ''<<new_card>>'' without confirmation
</$button>
</$list><!--new_pk-->
</$vars><!--new_card-->

TiddlyWiki\Button Set Field

8th January 2021 at 10:43am
AssignVariable TWCard UserAction
<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="yes"/>
Set UrCardPK = yes
</$button>

<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="no"/>
Set UrCardPK = no
</$button>

TiddlyWiki\Checkbox edit

8th January 2021 at 10:43am
AssignVariable TWCard UserAction
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler="$:/state/popup/checkUseIt">Use It</$checkbox>

TiddlyWiki\Clipboard Copy

8th January 2021 at 10:41am
AssignVariable TWCard UserAction

Tags = $:/tags/Macro

\define cboard_copy(ur_text)
<pre>$ur_text$</pre>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end
\define cboard_pwd(ur_text ur_pk)
<$reveal type="nomatch" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="show">Show</$button>

</$reveal>
<$reveal type="match" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="hide">Hide</$button>
<pre>$ur_text$</pre>
</$reveal>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end

TiddlyWiki\Code View or Copy data

8th January 2021 at 10:40am
CodeLibrary Extract TWCard

Title = mcr glbl_code_split

Tags = $:/tags/Macro

\define glbl_code_block(ur_card_pk)
[[$ur_card_pk$]]
<$codeblock code={{$ur_card_pk$}} />
\end
\define glbl_code_linenum(ur_card_pk, ur_skip_count, ur_section_size, ur_disp_linenum)
<div style="clear:both">[[$ur_card_pk$]]</div>
<$list filter="[[$ur_skip_count$]!match[]else[0]]" variable=intSKIP_COUNT>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>count[]]" variable=intLINE_COUNT>
<$list filter="[[$ur_section_size$]!match[]!match[0]else<intLINE_COUNT>]" variable=intSECTION_SIZE>
<$list filter="[range<intSECTION_SIZE>]" variable=intCUR_LINE>
<$list filter="[<intCUR_LINE>subtract[1]]" variable=IntREMOVE_LINE>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>butfirst<IntREMOVE_LINE>first[]]" variable=strCUR_LINE>
<$list filter="[[$ur_disp_linenum$]!match[n]!match[0]]"><div style="float:left"><<intCUR_LINE>></div></$list>
<$codeblock code=<<strCUR_LINE>> />
</$list></$list></$list></$list></$list></$list>
\end
\define glbl_code_split_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]splitregexp[\u0009]join[__	__]splitregexp[\u0020]join[__ __]splitregexp[\u0022\u0022\u0022]join[&#x0022;&#x0022;&#x0022;]]"><<currentTiddler>>
</$list></$list>
\end
\define glbl_code_split_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_split_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_split_data()
<$macrocall $name=glbl_code_split_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_split_next_group_disp(ur_rem_counter)
<$list filter="[{$ur_rem_counter$}subtract[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_split_disp(ur_source_card_pk, ur_temp_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to find: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
Source data: [[$ur_source_card_pk$]]<br>
\end
\define glbl_code_split_combine()
$(currentTiddler)$$(str_html_out)$
\end
\define glbl_code_split_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]add[1]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_card_pk>> text="" />
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_split(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_split_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_split_disp ur_source_card_pk=<<source_card_pk>> ur_temp_card_pk=<<temp_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$wikify name=str_html_out text=<<glbl_code_split_data>> >
        <$list filter="[<temp_card_pk>get[text]else[]]"><$vars combine_html_out=<<glbl_code_split_combine>> >
        <$action-setfield $tiddler=<<temp_card_pk>> text=<<combine_html_out>> />
         </$vars></$list>
        <$macrocall $name=glbl_code_split_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> />
        </$wikify>
      
      Find next 100 lines
      </$button><br>

    <$edit-text tiddler=<<temp_card_pk>> autoHeight=no />
    </$vars>
  </$list>
\end
\define glbl_code_disp_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u00A0]join[&nbsp;]splitregexp[\u0009]join[&nbsp;&nbsp;&nbsp;&nbsp;]splitregexp[\u0020]join[&nbsp;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]]"><<currentTiddler>><br></$list></$list>
\end
\define glbl_code_disp_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_disp_data()
<$macrocall $name=glbl_code_disp_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_disp_next_group_disp(ur_rem_counter, ur_oper)
<$list filter="[{$ur_rem_counter$}$ur_oper$[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_disp_disp(ur_source_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to browse: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
\end
\define glbl_code_disp_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_disp(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_disp_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
[[$ur_card_pk$]]<br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_disp_disp ur_source_card_pk=<<source_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="subtract" />
      
      Browse next 100 lines
      </$button><br>
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="add" />
      
      Browse prev 100 lines
      </$button><br>

    <<glbl_code_disp_data>>
    </$vars>
  </$list>
\end

<!--<$macrocall $name=glbl_code_disp ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_disp "WebNotes\Data 1 >>-->

<!--Does not pass through the \u0009 tab or \u00A0 non-breaking space characters. Chrome highlight and copy puts spaces on the clipboard.-->

<!--[[WebNotes\Data]]-->

<!--<$macrocall $name=glbl_code_split ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_block "UrCardPK">>-->

<!--<<glbl_code_linenum "UrCardPK" 0 15 n>>-->

TiddlyWiki\Codeblock Widget

8th January 2021 at 10:40am
CodeLibrary Formatting Text TWCard
```
sample code "here" and "there"
```

You can use the <$codeblock> widget to display text as the three-backticks TiddlyWiki formatting block. Make sure to put an enter at the end of the string if it ends with d-quotes.

<$codeblock code="""sample code "here" and "there"
"""/>

If you need to show text triple d-quotes in a code string, define a macro to return the string literal instead of passing in a code string.

\define sample_data_e3() sample code "here" and "there"

Make sure to put a leading space or some trailing comment text on any line within the macro that has \end by itself. Otherwise the macro definition will end early.

\define sample_data_e4()
sample
code """here"""
and "there"
\end <--Last line of macro

Another way to display a Card's content is by using the triple-curly-brace inclusion.

<$codeblock code={{{ [[UrCardPK]get[text]] }}}/>

TiddlyWiki\Compare Lines

8th January 2021 at 10:39am
Extract Formatting Text TWCard
<$diff-text source={{t1}} dest={{mcr glbl_section_disp}}/>

Name = mcr glbl_compare_lines

Tag = $:/tags/Macro

\define glbl_compare_lines_results_table(ur_card_pk, ur_second_pk, ur_row_count)
<table><tr>
<th>''Line''</th>
<th>Show text</th>
<th>First Side<br>Second Side</th>
</tr>
<$list filter="[range<intSECOND_COUNT>subtract[1]]" variable="intCUR_ENTRY">
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]]" variable="strFIRST_LINE">
<$list filter="[{$ur_second_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]!match<strFIRST_LINE>]" variable="strSECOND_LINE">
<tr>
<td rowspan=2>

!!<<intCUR_ENTRY>>
</td>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection1" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine1}!match[]else[0]]" variable=intSTART_LINE><$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_card_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection1"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strFIRST_LINE>> /></td>
</tr>
<tr>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection2" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine2}!match[]else[0]]" variable=intSTART_LINE>
<$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_second_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_second_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection2"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strSECOND_LINE>> /></td>
</tr>
</$list></$list></$list>
</table>
\end
\define glbl_compare_lines(ur_card_pk, ur_second_pk)
<$list filter="[{$ur_card_pk$}splitregexp[\n]count[]]" variable="intFIRST_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]]" variable="intSECOND_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]subtract<intFIRST_COUNT>]" variable="intSECOND_EXTRA">

[[$ur_card_pk$]] line count: <<intFIRST_COUNT>>

[[$ur_second_pk$]] line count: <<intSECOND_COUNT>>

''$ur_second_pk$'' excess line count: ''<<intSECOND_EXTRA>>''

<$macrocall $name=glbl_compare_lines_results_table ur_card_pk="$ur_card_pk$" ur_second_pk="$ur_second_pk$" ur_row_count=<<intSECOND_COUNT>> />
</$list>
</$list>
</$list>
\end

<!--
<$edit-text tiddler="$:/state/popup/CompareText1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>
<$edit-text tiddler="$:/state/popup/CompareText2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>

<<glbl_compare_lines "$:/state/popup/CompareText1" "$:/state/popup/CompareText2">>
-->

TiddlyWiki\Construct a Calendar

8th January 2021 at 10:39am
Extract Formatting Numbers TWCard
\define CalendarEntryDay(ur_ymd,ur_d,ur_cur_date)
<$list filter='$ur_ymd$ +[match[$ur_cur_date$]]'>
//''<span style="background-color:yellow">$ur_ymd$</span>''//<br>
</$list>
<$list filter='[prefix[$ur_ymd$]count[]match[0]]'>
<$list filter='$ur_ymd$ +[!match[$ur_cur_date$]]'>
$ur_ymd$<br>
</$list>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]match[1]]">
''d$ur_d$''<br><<currentTiddler>> entry<br>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]!match[0]!match[1]]">
''d$ur_d$''<br><<currentTiddler>> entries<br>
</$list>
\end

\define CalendarEntryMonth(ur_ym,ur_d,ur_cur_date)
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]!match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d0$ur_d$" ur_d="0$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d$ur_d$" ur_d="$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
\end

\define CalendarListDailyThings(day month year)
<$button class='tc-btn-invisible' style='width:100%;height:100%'>
<div style='height:100%;width:100%;position:relative;text-align:left;vertical-align:top;z-index=0'>

<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]!match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_ym="$year$m0$month$" ur_d="$day$"  ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_m="$year$m$month$" ur_d="$day$" ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>


</div>
</$button>
\end
\define date_list_entry(ur_num,ur_cur_date)
<$list filter="[[$ur_num$]match[$ur_cur_date$]]">
//''<span style="background-color:yellow">$ur_cur_date$</span>''//<br>
</$list>
<$list filter="[prefix[$ur_num$]count[]!match[0]]">
<$list filter="[[$ur_num$]!match[$ur_cur_date$]count[]!match[0]]">
$ur_num$<br>
</$list>
</$list>
<<list-links filter:"[prefix[$ur_num$]]" >>
\end
\define date_list_dayunit(ur_num,ur_cur_date)
<$list filter="$ur_num$0 $ur_num$1 $ur_num$2 $ur_num$3 $ur_num$4 $ur_num$5 $ur_num$6 $ur_num$7 $ur_num$8 $ur_num$9">
<$macrocall $name="date_list_entry" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list_daydec(ur_year_month,ur_num,ur_cur_date)
<$list filter="$ur_year_month$d0 $ur_year_month$d1 $ur_year_month$d2 $ur_year_month$d3 $ur_year_month$d4 $ur_year_month$d5 $ur_year_month$d6 $ur_year_month$d7 $ur_year_month$d8 $ur_year_month$d9">
<$macrocall $name="date_list_dayunit" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list(ur_year,ur_month)
<$calendar-month year="$ur_year$" month="$ur_month$" />

<$macrocall $name="date_list_daydec" ur_year_month="$ur_year$m$ur_month$" ur_num=<<currentTiddler>> ur_cur_date=<<now YYYYm0MMd0DD>> />
\end

TiddlyWiki\Core Macro Definition

8th January 2021 at 10:39am
Extract FileSystem TWCard
  • Title = mcr glbl_core_mcr_def
  • Tag = $:/tags/Macro
\define glbl_core_mcr_def(ur_macro_name)
<$list variable=cur_pk filter="""[[$:/core]get[text]split[define $ur_macro_name$(]butfirst[]split[\n\\end]first[]addprefix[define $ur_macro_name$(]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">
<$codeblock code=<<cur_pk>> />
</$list><!--cur_pk-->
\end
  • Show all Core macro names and source code
<$list variable=show_code_pk filter="[<currentTiddler>split[Draft of]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-checkShowCode]]">
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>

<$list variable=cur_def_text filter="[[$:/core]get[text]split[define ]!prefix[{]!prefix[the]sort[]]">
<$list variable=cur_macro_name filter="[<cur_def_text>split[(]first[]]">
<$list variable=cur_end_text filter="""[<cur_def_text>split[\n\\end]first[]addprefix[define ]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">

!! <<cur_macro_name>>
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]match[yes]]"><$codeblock code=<<cur_end_text>> />
</$list><!--cur_showcode_text-->

</$list><!--cur_end_text-->
</$list><!--cur_macro_name-->
</$list><!--cur_def_text-->
</$list><!--show_code_pk-->

TiddlyWiki\CSS Classes

8th January 2021 at 10:38am
CSSCode Formatting TWCard

New Card page

.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}

Note: The @@ directive must include the leading period (.) to select a CSS class

@@.alternating-rows
<table>
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

TiddlyWiki\CSS without classes

8th January 2021 at 10:38am
CSSCode Formatting TWCard

Apply stylesheet to all cards

.tc-tiddler-body {
  word-break: normal; 
  word-wrap: break-word;
  white-space: pre-wrap;
} 
  • Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

Apply stylesheet to cards with specific tag linewrap

[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
  • Note: Only cards with the linewrap tag will use this stylesheet change

Apply Styles to In-line Text

  • Start a text block with @@ and the CSS styles with no spaces

Sample Code:

@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line

Result:

These are
separate lines
here

This is one big line
  • or start in the middle of a text block

Sample Code:

This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.

Result:

This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.

TiddlyWiki\Data Tiddler

8th January 2021 at 10:37am
AssignVariable FileSystem TWCard

Type = application/x-tiddler-dictionary

3:a
2:b
3:c

See list of unique indexes:

<$list variable=cur_key filter="[[UrPK]indexes[]]"><<cur_key>>: 
<$list variable=cur_val filter="[[UrPK]getindex<cur_key>]"><<cur_val>><br>
</$list><!--cur_val-->
</$list><!--cur_key-->

Use one value (last one if an index is duplicated):

-{{UrPK##3}}-

VBNetCode\Text file to JSON Lines

TiddlyWiki\Date Part

8th January 2021 at 10:37am
Extract Formatting Numbers TWCard

Tag = $:/tags/Macro

\define glbl_dt_ddd()
<div style="clear:right;float:right;background-color:aquamarine;"><<now "YYYYm0MMd0DD DDD pm0hh12\m0mm">></div>
<$list filter="[<currentTiddler>split[Draft of ']join[]split[ ]first[]split[m]join[]split[d]join[]]">
<$view field="title" format="date" template="[UTC]DDD" />
</$list>
\end
TokenSubstituted Value
DDDDay of week in full (eg, "Monday")
dddShort day of week (eg, "Mon")
DDDay of month
0DDAdds a leading zero
DDthAdds a suffix
WWISO-8601 week number of year
0WWAdds a leading zero
MMMMonth in full (eg, "July")
mmmShort month (eg, "Jul")
MMMonth number
0MMAdds leading zero
YYYYFull year
YYTwo digit year
wYYYYFull year with respect to week number
wYYTwo digit year with respect to week number
hhHours
0hhAdds a leading zero
hh12Hours in 12 hour clock
0hh12Hours in 12 hour clock with leading zero
mmMinutes
0mmMinutes with leading zero
ssSeconds
0ssSeconds with leading zero
XXXMilliseconds
0XXXMilliseconds with leading zero
am or pmLower case AM/PM indicator
AM or PMUpper case AM/PM indicator
TZDTimezone offset
\xUsed to escape a character that would otherwise have special meaning
[UTC]Time-shift the represented date to UTC. Must be at very start of format string

TiddlyWiki\Decimal To Hex

8th January 2021 at 10:37am
Extract Numbers TWCard

Name = mcr glbl_dec_to_hex5
Tag = $:/tags/Macro

\define glbl_dec_to_hex5(ur_code)
<$list filter="[[$ur_code$]divide[16]divide[16]divide[16]divide[16]floor[]]" variable=lvl_x4>
<$list filter="[<lvl_x4>multiply[16]multiply[16]multiply[16]multiply[16]]" variable=lvl_d4>
<$list filter="[[$ur_code$]subtract<lvl_d4>divide[16]divide[16]divide[16]floor[]]" variable=lvl_x3>
<$list filter="[<lvl_x3>multiply[16]multiply[16]multiply[16]]" variable=lvl_d3>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>divide[16]divide[16]floor[]]" variable=lvl_x2>
<$list filter="[<lvl_x2>multiply[16]multiply[16]]" variable=lvl_d2>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>divide[16]floor[]]" variable=lvl_x1>
<$list filter="[<lvl_x1>multiply[16]]" variable=lvl_d1>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>subtract<lvl_d1>]" variable=lvl_xrem>
<$list filter="[range[15]butfirst[9]match<lvl_x4>add[55]] [range[10]subtract[1]match<lvl_x4>add[48]]" variable=lvl_h4>
<$list filter="[range[15]butfirst[9]match<lvl_x3>add[55]] [range[10]subtract[1]match<lvl_x3>add[48]]" variable=lvl_h3>
<$list filter="[range[15]butfirst[9]match<lvl_x2>add[55]] [range[10]subtract[1]match<lvl_x2>add[48]]" variable=lvl_h2>
<$list filter="[range[15]butfirst[9]match<lvl_x1>add[55]] [range[10]subtract[1]match<lvl_x1>add[48]]" variable=lvl_h1>
<$list filter="[range[15]butfirst[9]match<lvl_xrem>add[55]] [range[10]subtract[1]match<lvl_xrem>add[48]]" variable=lvl_hrem>
<$wikify name=str_hex_out text="0x&#<<lvl_h4>>;-&#<<lvl_h3>>;&#<<lvl_h2>>;&#<<lvl_h1>>;&#<<lvl_hrem>>;" >
<<str_hex_out>>
</$wikify>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
\end

TiddlyWiki\Delete All Cards with Tag

8th January 2021 at 10:36am
AssignVariable FileSystem TWCard
<$button>
<$list filter="[tag[ARTICLE]]"><$action-sendmessage $message=tm-delete-tiddler $param=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards with Confirmation
</$button>

<$button>
<$list filter="[tag[ARTICLE]]"><$action-deletetiddler $tiddler=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards without Confirmation
</$button>

<$button>
<$list filter="[tag[DOC]]" variable=doc_pk><$list filter="[<doc_pk>fields[]prefix[e]]" variable=field_pk2><$action-deletefield $tiddler=<<doc_pk>> $field=<<field_pk2>> /></$list></$list>
Del fields starting with `E` in DOC tagged Cards
</$button>

TiddlyWiki\DivPop btn

8th January 2021 at 10:36am
FileSystem TWCard UserAction

DivPop.svg

Tag = $:/tags/ViewToolbar

\define divpop_current(ur_ref)
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text="$ur_ref$"/>
<$action-sendmessage $message="tm-close-tiddler" $param="pop_right"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{DivPop.svg}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text="Popup over Sidebar"/></span>
</$list>
</$button>
\end

<$list filter="[all[current]]">
<$macrocall $name=divpop_current ur_ref=<<currentTiddler>> /> 
</$list>

TiddlyWiki\DivPop glbl

8th January 2021 at 10:36am
FileSystem TWCard UserAction

Tag = $:/tags/BelowStory

<$list filter="[{$:/state/popup/DivPopTitle}is[tiddler]]">
<div style="
position: fixed;
top: 0px;
right: 0px;
width: 350px;
border: 3px solid;
background: white;
bottom: 0%;
">
<div style="overflow-y: scroll; height: 100%;">
<$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
close
</$button>
<$tiddler tiddler=<<currentTiddler>> >
<$transclude mode="block" />
</$tiddler>
</div>
</div>
</$list>

TiddlyWiki\Embed Font

8th January 2021 at 10:35am
FileSystem Formatting Text TWCard

[https://tiddlywiki.narkive.com/bS0CgWKQ/tw-tw5-how-to-embed-a-font-using-font-face-and-data-url]
- Visit: http://www.fontsquirrel.com/tools/webfont-generator
- Upload your font file (".ttf", ".eot", ".woff", etc)
- Select option "Expert"
- Check the option case at CSS >> Base64 Encode
- Generate your webkit -> Downloads file

[stylesheet.zip file]
- Unpack ZIP file -> Downloads file

[stylesheet.css]
- Note: The file's content in Base64 encoded

[Wiki file]
- Drag-drop file to import -> Creates Card
- [styleshee.css Card]
- Make sure the field font-family is what you want
- Tag = $:/tags/Stylesheet
- Tiddler type = Plain text (text/plain)
- Create a new Card and use the font

TiddlyWiki\Encrypt file

8th January 2021 at 10:35am
AssignVariable FileSystem TWCard

[Wiki file]
- [Sidebar, Tools tab]
- Click button Set Password -> Opens dialog
- Password = UrPasswordText
- Repeat password = UrPasswordText
- Click button Set Password -> Closes dialog

[keyboard action SaveAllChanges]
- [<$action-sendmessage $message="tm-download-file"]
- Comment out this tag to keep the HTML Wiki version from being exported
- Save the Wiki file

- Note: The password will be required to start the Wiki application when you open the Wiki file

TiddlyWiki\External Link organization

8th January 2021 at 10:34am
FileSystem Formatting TWCard
  • Create one Card for each external link in this format
    • Title always starts with ext and a space, then the external link description
    • Tagged as EXT
    • Contains one line in this format:
[ext[ur_url]]
  • Reference the Card with the ext macro, but don't include the ext prefix or the leading space
  • The link is shown, and there will be -> on the right side of the Card window
  • This flags links that will open in a new tab, and allows you to easily open the ext Card and change the saved link
<<ext "UrExternalLinkDiscption">>
  • Global macro
\define ext(ur_extcard_pk)
{{ext $ur_extcard_pk$}}<div style="float:right">[[_|ext $ur_extcard_pk$]]</div>
\end

TiddlyWiki\Filter Operators

8th January 2021 at 10:34am
CodeLibrary Filter TWCard

Math

abs - calculate the absolute value of a list of numbers
add - treating each input title as a number, add to each the numeric value of the operand
ceil - rounds a list of numbers up to the next largest integer
divide - treating each input title as a number, divide them by the numeric value of the operand
exponential - convert each number to exponential notation with N digits
fixed - convert each number to fixed point notation with N digits after the decimal point
floor - rounds a list of numbers to the largest integer less than or equal to each number
max - treating each input title as a number, take the maximum of its value and the numeric value of the operand
maxall - find the largest of a list of numbers
min - treating each input title as a number, take the minimum of its value and the numeric value of the operand
minall - find the smallest of a list of numbers
multiply - treating each input title as a number, multiply it by the numeric value of the operand
negate - calculate the negation of a list of numbers
precision - convert each number to a string with N significant digits
product - produce the product of the input numbers
remainder - treating each input title as a number, return the remainder when divided by the numeric value of the operand
round - rounds a list of numbers to the nearest integer
sign - return -1, 0 or 1 for a list of numbers according to whether each number is negative, zero, or positive
subtract - treating each input title as a number, subtract from each the numeric value of the operand
sum - produce the sum of the input numbers
trunc - truncates a list of numbers to their integer part, removing any fractional part
untrunc - rounds a list of numbers to the next integer with largest absolute value, that is, away from zero

TiddlyWiki\Fonts via URL

8th January 2021 at 10:35am
FileSystem Formatting Text TWCard
<link href='https://fonts.googleapis.com/css?family=Playfair Display' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Sofia' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Alex Brush' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Akronim' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Annie Use Your Telescope' rel='stylesheet'>

@@font-family: 'Playfair Display';
!'Playfair Display'  1234567890 ABC abc
@@

@@font-family: 'Sofia';
!'Sofia'  1234567890 ABC abc
@@

@@font-family: 'Alex Brush';
!'Alex Brush'  1234567890 ABC abc
@@

@@font-family: 'Akronim';
!'Akronim'  1234567890 ABC abc
@@

@@font-family: 'Annie Use Your Telescope';
!'Annie Use Your Telescope'  1234567890 ABC abc
@@

TiddlyWiki\Global Card Footer

8th January 2021 at 10:34am
FileSystem Formatting TWCard

Every Card shows the Wikified content of the Card content, followed by the Wikified content of every Card with the tag $:/tags/ViewTemplate.

Example Footer Text

Create a new Card

template Global Footer

Any Text Here

Add the tag:

And then every Card will show the words "Any Text Here" at the bottom of the Card.

Example Footer Home Button

Create a new Card

template Home Button

<div style="float:right">{{$:/core/ui/Buttons/home}}</div>

Add the tag:

And then every Card will show the "Home" icon at the bottom-right of the Card.

TiddlyWiki\Global Macro

8th January 2021 at 10:33am
FileSystem TWCard

Tag = $:/tags/Macro

TiddlyWiki\Group Totals

8th January 2021 at 10:33am
CodeLibrary Filter Numbers TWCard
unique_groups()
- find list of titles with UrAttribute
    - [has[UrAttribute]]
- split by the prefix before the first hyphen
    - [<currentTiddler>split[-]nth[1]]
- return each title's prefix followed by a space
    - ><<currentTiddler>> <

unique_counts()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces
    - [<ugrp>split[ ]
- ignore white-space only entries, and sort the rest alphabetically
    - !match[]sort[]
- use "each:value" to get the unique title prefixes in the list
    - each:value[]]
- for each unique title prefix, get a count of titles with UrAttribute
    - [has[UrAttribute]prefixcount[]]

count_size()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces, ignore white-space, sort, use "each:value", store as ur_entry
    - [<ugrp>split[ ]!match[]sort[]each:value[]]
    - ur_entry=<<currentTiddler>>
- for each unique title prefix, only continue where the count of titles with UrAttribute matches the parent unique count
    - [has[UrAttribute]prefix<ur_entry>count[]match[$(currentTiddler)$]]
- find all the titles with the unique title prefix, and return a "1" for each entry
    - [has[UrAttribute]prefix]">1 <

main()
- create a new variable ucnt with the list of title prefixes from unique_counts()
    - <$wikify name=ucnt text=<<unique_counts>>
- split the new variable by spaces, ignore white-space, sort, use "each:value"
    - [split[ ]trim[]!match[]sort[]each:value[]]
- For each unique count,
    - list the entry
    - sum the number of entries returned from count_size() divided by the unique count
\define unique_groups()
<$list filter="[has[eng-vocab]]"><$list filter="[<currentTiddler>split[-]nth[1]]"><<currentTiddler>> </$list></$list>
\end
\define unique_counts()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]">
<$list filter="[has[eng-vocab]prefix<currentTiddler>count[]]"><<currentTiddler>> </$list>
</$list>
</$wikify>
\end
\define count_size()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]"><$vars ur_entry=<<currentTiddler>> >
<$list filter="[has[eng-vocab]prefix<ur_entry>count[]match[$(currentTiddler)$]]">
<$list filter="[has[eng-vocab]prefix<ur_entry>]">1 </$list>
</$list>
</$vars></$list>
</$wikify>
\end
<$wikify name=ucnt text=<<unique_counts>> >
<$list filter="[<ucnt>split[ ]trim[]!match[]sort[]each:value[]]">
ASLSJ Prefix Groups with <<currentTiddler>> words -
<$wikify name=usize text=<<count_size>> >
<$list filter="[<usize>split[ ]trim[]!match[]sum[]divide<currentTiddler>]"><<currentTiddler>><br>
</$list>
</$wikify>
</$list>
</$wikify>

TiddlyWiki\Hard Line Breaks

8th January 2021 at 10:32am
Formatting Text TWCard

HTML normally ignores line breaks. TiddlyWiki uses HTML, and includes a way to stop ignoring line breaks.

[TiddlyWiki editor] - Type three double-quotes (""") and press enter to ignore line breaks below this point - The (""") does not show up in the output

Three double-quotes will start a hard line breaks section

"""
line one blends into line two continues

"""
line three stops
line four starts
"""

line one blends into line two continues

line three stops
line four starts

HTML Preformatted text with Sans-Serif font

<pre style="font-family: sans-serif;">line three stops line four starts</pre>

line three stops
line four starts

TiddlyWiki\Hidden on Static File

10th January 2021 at 7:40pm
FileSystem Formatting TWCard

Hide section when exported to static HTML file

<$list filter="[<tv-config-toolbar-icons>match[no]]">

TiddlyWiki\iFrame

8th January 2021 at 10:32am
Extract FileSystem HTMLCode TWCard

Use an iFrame to run JavaScript in a TiddlyWiki

>iframe src="javascript:newWindow='';var ...

- just javascript:newWindow=var ... did not compile. An empty string is a work-around.

Alternative output: use alert instead of document.write

alert(strTEXT);"/>

How to reference an external HTML file in a tiddler

>iframe src=...  scrolling=yes style="border-style:none;height:100%;width:100%">
>/iframe>

- A self-closing tag does not allow remaining html code to be displayed - ALWAYS specify a closing >/iframe> tag

TW Macro to show iframe and link

>div style='float:right'>[ext[_ |$ur_pk$.txt.html]]
>/div>
>iframe src='$ur_pk$.txt.html'>
>/iframe>

- $macrocall $name=iframe_txt ur_pk= currentTiddler

<iframe src="javascript:newWindow='';var qs = '&quot;';var qt = '&apos;';

var objFRAME = document.createElement('iframe');
objFRAME.setAttribute('id', 'innerFrame');
objFRAME.setAttribute('src', 'http://www.google.com/');
document.body.appendChild(objFRAME); 
var objTEST = objFRAME;
var strTEXT = '';
if (objTEST===undefined) {
strTEXT = 'undef obj';
} else if (objTEST===null) {
strTEXT = 'null obj';
} else {
var intSEQ = 0;
var strNAME;
for (strNAME in objTEST) {
intSEQ += 1;
strTEXT += ' ; ' + strNAME;
}
strTEXT = 'olen ' + intSEQ + strTEXT;
}
document.write(strTEXT);"></iframe>

alert(strTEXT);"/>

<iframe src='iframe.scrE2.txt' height=100% width=100% scrolling=yes frameborder=no></iframe>


\define iframe_txt(ur_pk)
<div style="float:right">[ext[_ |$ur_pk$.txt.html]]</div>
<iframe src='$ur_pk$.txt.html' scrolling=yes style="border-style:none;height:100%;width:100%"></iframe>
\end

TiddlyWiki\Ignore WikiText formatting

11th January 2021 at 12:00am
Formatting Text TWCard

Use the TextWidget to ignore WikiText formatting

  • widget name = $text
  • text attr = `still black colored text`

Sample code

<$text text="`still black colored text`" />

Results:

`still black colored text`

Use the Rules card pragma to ignore WikiText formatting

  • [New card]
  • Put \rules only at the top of the card text

Sample code

\rules only
`still black colored text`

Results:

`still black colored text`

Use the Card Datatype to ignore WikiText formatting

  • [New card]
  • type field = text/plain

Sample code

`still black colored text`

Results:

`still black colored text`

TiddlyWiki\Image

8th January 2021 at 10:30am
Formatting TWCard

Link an image in a Tiddler with 500px width
- Have image tiddler
- Have text tiddler
- Apply image to text tiddler at 500px width

[New tiddler]
- title = mcr img_link
- tag = $:/tags/Macro
- text field code

\define img_link(ur_pk)
@@max-width:500px;
[img [$ur_pk$]]
@@
\end

[Text tiddler]
- $macrocall $name=img_link ur_pk= currentTiddler

TiddlyWiki\Image link opens Card

8th January 2021 at 10:29am
FileSystem TWCard UserAction

Tag = $:/tags/Macro

\define glbl_image_high(ur_image_pk, ur_size:200)
<$link to="$ur_image_pk$">[img height=$ur_size$px [$ur_image_pk$]]</$link>
\end
\define glbl_image_wide(ur_image_pk, ur_size:500)
<$link to="$ur_image_pk$">[img width=$ur_size$px [$ur_image_pk$]]</$link>
\end

TiddlyWiki\Import Macros

8th January 2021 at 10:29am
FileSystem TWCard
\import [[mcr date_list]]

TiddlyWiki\Javascript Calculation in Bookmarklet

8th January 2021 at 10:59am
Bookmarklet Extract JavaScriptCode TWCard
  • Click the button to copy the text to a javascript bookmarklet
  • Open a new tab
  • Type the letter "j" in the address bar, paste in the clipboard text, and press enter
  • The Javascript alert box shows the message
\define glbl_copyto_js_bookmarklet(ur_js_code)
<pre>$ur_js_code$</pre>
<$macrocall $name="copy-to-clipboard" src="""avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){const el = newWindow.document.createElement('textarea');const ur_str='$ur_js_code$';try {el.value =eval(ur_str)}catch(err) {el.value = err.message;}; newWindow.document.body.appendChild(el); el.select();void(newWindow.focus());}""" />
\end

<!--|v
<<glbl_copyto_js_bookmarklet """parseInt("FF",16).toString(10);""">>
^|-->

TiddlyWiki\Keep words together on one line

9th January 2021 at 8:47am
Formatting Text TWCard

Use CSS white-space tag

  • The CSS white-space:nowrap; disables normal text wrapping
  • This is useful when you have several smaller phrases that should not be separated visually onto different lines
  • Note: This can make the line extend past the edge of the browser window, requiring scrolling to see the rest

Sample Code that can split phrases

A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)

Results:

A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)

Sample Code that can keeps short phrases together

@@white-space:nowrap;A code line (1)@@ @@white-space:nowrap;A code line (2)@@ @@white-space:nowrap;A code line (3)@@ @@white-space:nowrap;A code line (4)@@ @@white-space:nowrap;A code line (5)@@ @@white-space:nowrap;A code line (6)@@ @@white-space:nowrap;A code line (7)@@ @@white-space:nowrap;A code line (8)@@ @@white-space:nowrap;A code line (9)@@ @@white-space:nowrap;A code line (10)@@ @@white-space:nowrap;A code line (11)@@ @@white-space:nowrap;A code line (12)@@ @@white-space:nowrap;A code line (13)@@ @@white-space:nowrap;A code line (14)@@

Results:

A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)

TiddlyWiki\Keyboard Shortcut

8th January 2021 at 10:28am
CodeLibrary TWCard UserAction

Pre-requisites

  • You need a ur_message_to_send to replace in the below steps
    • tm-home is an example message that TiddlyWiki can do
  • You need a ur_card_pk to replace in the below steps
    • It should describe the desired action

Setup keyboard shortcut

[New Card]

[New Card]

alt-H

[New Card]

((ur_card_pk))
  • Main Body Text =
<$action-sendmessage $message="ur_message_to_send"/>

TiddlyWiki\List Links from Numbered Fields

8th January 2021 at 9:03am
Filter Numbers TWCard
<ol>
<$list filter="[<currentTiddler>fields[]prefix[e]sort[]]" variable=lookup_name>
<$list filter="[<currentTiddler>get<lookup_name>]" variable=ref_card_pk>
<$list filter="[<ref_card_pk>get[img]else[]]" variable=ref_img_pk>
<li><$link to=<<ref_card_pk>> />@@float: right;overflow: auto;vertical-align: top;padding-left: 10px;<$image width=200px source=<<ref_img_pk>> />@@<div style="clear:both;"></div></li>
</$list>
</$list>
</$list>
</ol>

TiddlyWiki\List Links of Prefixed Cards

8th January 2021 at 9:02am
Filter TWCard
<ol>
<$list filter="[<currentTiddler>addsuffix[\]]">
<$list filter="[all[tiddlers]prefix<currentTiddler>sort[]]">
<li><$link to=<<currentTiddler>> /></li>
</$list>
</$list>
</ol>

TiddlyWiki\List Links standard

8th January 2021 at 9:02am
Filter TWCard
<<list-links filter:"[tag[DOC]field:level[1]sort[title]] [tag[DOC]field:level[]sort[title]]">>

TiddlyWiki\List Widget

8th January 2021 at 9:01am
Filter TWCard

Content and Attributes

The content of the <$list> widget is an optional template to use for rendering each tiddler in the list.

The action of the list widget depends on the results of the filter combined with several options for specifying the template:

  • If the filter evaluates to an empty list, the text of the emptyMessage attribute is rendered, and all other templates are ignored
  • Otherwise, if the template attribute is specified then it is taken as the title of a tiddler to use as a template for rendering each item of the list
  • Otherwise, if the list widget content is not blank, it is used as a template for rendering each item of the list
  • Otherwise, a default template is used consisting of a <span> or <div> element wrapped around a link to the item
AttributeDescription
filterThe tiddler filter to display
templateThe title of a template tiddler for transcluding each tiddler in the list. When no template is specified, the body of the ListWidget serves as the item template. With no body, a simple link to the tiddler is returned.
editTemplateAn alternative template to use for DraftTiddlers in edit mode
variableThe name for a variable in which the title of each listed tiddler is stored. Defaults to currentTiddler
emptyMessageMessage to be displayed when the list is empty
storyviewOptional name of module responsible for animating/processing the list
historyThe title of the tiddler containing the navigation history

Additional Notes and Edge Cases

  • If the filter attribute is not present then a default of [!is[system]sort[title]] is used
  • If the list widget is completely empty (ie only whitespace between the opening and closing tags), then it behaves as if the content were a DIV or a SPAN containing a link to the current tiddler (it’s a DIV if the list widget is in block mode, or a SPAN if it is in inline mode)
  • If the template attribute is not present then the content of the list widget will be used as the template, unless the widget is completely empty in which case a default template is used

TiddlyWiki\Local Video or Audio Files

8th January 2021 at 9:01am
Audio CodeLibrary FileSystem TWCard Video
<video width="320" height="180"
poster="video\Frozen Sleep - Cortana Tribute by Malukah.png"
controls preload="none">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.webm" type=
"video/webm">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.ogv" type=
"video/ogg">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.mp4" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
<audio controls preload="none">
<source src="audio\Frozen-Sleep-Malukah.ogg" type="audio/ogg">
<source src="audio\Frozen-Sleep-Malukah.mp3" type="audio/mp3">
<p>Your browser does not support the HTML 5 audio tag.</p>
</audio>

TiddlyWiki\Pagination

8th January 2021 at 9:00am
Filter Formatting Text TWCard
\define page_next()
<$list variable="filter_prev_page" filter="[<page_pk>get[text]!match[0]!match[]]">
<$button style="margin-left:30px">
<$action-setfield $tiddler=<<page_pk>> text=""/>
First page
</$button>

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>subtract[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/></$list>
Previous page
</$button>
</$list><!--filter_prev_page-->

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>add[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/><$action-navigate $to=<<card_pk>> $scroll="yes"/></$list>
Next page
</$button><br>
<!--***page_next***-->
\end
<$list variable="card_pk" filter="[<currentTiddler>]">
<$list variable="popup_pk" filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]">

<$list variable="page_pk" filter="[<popup_pk>addsuffix[-cur_page]]">
<$list variable="cur_page_skip" filter="[<page_pk>get[text]!match[]else[0]]">
<$list variable="cur_page_num"filter="[<cur_page_skip>add[1]]">
<$list variable="cur_page_through" filter="[<cur_page_num>subtract[1]add[10]]">
<<page_next>>

<$list variable="subdir_count" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]count[]]">

Subdirectories <<cur_page_num>> through <<cur_page_through>>

Number of subdirectories: <<subdir_count>><br>
<$list variable="cur_subdir_path" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]butfirst<cur_page_num>first[10]]">

<$list variable="raw_image_count" filter="[{File List Data}splitregexp[\n]prefix<cur_subdir_path>uppercase[]suffix[.JPG]count[]addprefix[ (]addprefix<cur_subdir_name>addsuffix[ photo]]">
<<raw_image_count>>
</$list><!--raw_image_count-->

</$list><!--cur_subdir_path-->
</$list><!--subdir_count-->
<<page_next>>
</$list><!--cur_page_through-->
</$list><!--cur_page_num-->
</$list><!--page_pk-->
</$list><!--popup_pk-->
</$list><!--card_pk-->

TiddlyWiki\Popup State Clear All

8th January 2021 at 9:00am
AssignVariable CodeLibrary TWCard
<$list filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]" variable="popup_pk">
<$button>
<$list filter="[all[tiddlers]prefix<popup_pk>has[text]]" variable=del_pk><$action-deletefield $tiddler=<<del_pk>> $field="text"/></$list>
Show All
</$button><br>

</$list>

TiddlyWiki\Published Tools

8th January 2021 at 9:00am
CodeLibrary TWCard

https://dynalist.io/d/zUP-nIWu2FFoXH-oM7L7d9DM#z=zdF80rIaJ79W5P0IGsjYIjkD

[Ace editor](http://innoq.tiddlyspot.com/)
[ActionIncrement widget](https://skeeve.github.io/tw5-plugins/) - The action-increment widget is an action widget that retrieves a value from a text reference. It will then increase the first digit-sequence found in that text and store it.
[Ad-Hoc Macro](https://tobibeer.github.io/tb5/#Ad-Hoc%20Macro) - evaluate any text as an ad-hoc macro even passing variables.
[Amazon Web Services Plugin](https://tiddlywiki.com/#OfficialPlugins) - provides several tools for working with Amazon Web Services **(official TW plugin)**
[Delay Actions](https://groups.google.com/forum/#!topic/tiddlywiki/z7SGLAPODW8), defer the execution of action widgets for a set amount of time
[CouchDB adaptor](https://github.com/wshallum/couchadaptor)
[Count (tobibeer)](http://tobibeer.github.io/tw5-plugins/#count) - A filter to count titles or compare against a specified count
[Demo Code Macro](http://ooktech.com/jed/ExampleWikis/DemoCodeMacro/) - This is an attempt to make a macro that can be used to demonstrate wikitext code fragments in an interactive way.
[dom (tobibeer)](http://tobibeer.github.io/tw5-plugins/#dom) - retrieve text or attributes from dom nodes
[eval (tobibeer)](http://tobibeer.github.io/tw5-plugins/#eval) - Evaluate expressions, compute and compare tiddler properties and data
[Fargo.io integration](http://blog.jeffreykishner.com/2014/01/24/note-taking-bookmarklets-for-fargoio-and-tiddlywiki-.html)
[Global macros, instructions on how to make](http://tw5magick.tiddlyspot.com/)
[Highlight plugin](https://tiddlywiki.com/plugins/tiddlywiki/highlight/#%24%3A%2Fplugins%2Ftiddlywiki%2Fhighlight) **(official TW plugin)** - description: Plugin that activates syntax highlighting of code blocks using v8.8.0 of highlight.js from Ivan Sagalaev. demo [here](https://tiddlywiki.com/plugins/tiddlywiki/highlight/)
[HTAlink](http://welford.github.io/) - Will only work in offline hta editions of this page. Launches external links in your default browser and not IE
[ifAisB](https://tid.li/tw5/hacks.html) - This macro allows to test if a value A – a variable or a transcluded value – matches a value B and to react accordingly. It works almost like an if-then-else statement.
[IfTid Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the existence of a tiddler (or field) and to send different widget messages based upon the existence of this tiddler (or field.)
[IfTref Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the value of a TextReference and to send different widget messages based upon whether this value matches the value specified by the 'value=' attribute.
[Incremental load command](http://malsandbox.tiddlyspot.com/) - only loads tiddlers that either don't already exist in the tiddlers folder, or have a newer modified date than the existing tiddler.
[Javascript macros in wikitext](http://tw5magick.tiddlyspot.com/)
[JSON editor (btheado)](http://btheado.github.io/jsoneditor.html)
[JSON editor (bjtools)](http://bjtools.tiddlyspot.com/)
[JsonMangler](https://joshuafontany.github.io/TW5-JsonMangler/) - This plugin changes the methods tiddlywiki uses to retrieve and set values in json data tiddlers. It does this in a way that aims for backwards compatibility.

[keyboard-snippets plugin](http://braintest.tiddlyspot.com/#keyboard-snippets)
[LetWidget](http://tiddlystuff.tiddlyspot.com/) - The LetWidget is an enhancement of the SetWidget.
[mforth](https://quaraman.de/tw/mforth.html) - It is a forth like language in a tiddlywiki macro. Forth operates with Reverse Polish Notation (RPN for short).
[Mousetrap](http://welford.github.io/) - simple library for handling keyboard shortcuts in Javascript.
[muut integration](http://ooktech.com/jed/ExampleWikis/TiddlyWiki-muut/)
[Nodewebkitsaver plugin](http://ooktech.com/jed/ExampleWikis/SetFilters/#%24%3A%2Fplugins%2FOokTech%2FSetFilters) - provides a saver module for saving changes when using [TiddlyWiki](http://ooktech.com/jed/ExampleWikis/SetFilters/#TiddlyWiki) directly under NW.js (previously known as node-webkit).
[Pack as plugin](http://braintest.tiddlyspot.com/#Pack%20as%20plugin) - Beta version
[Pan widget](http://muritest.tiddlyspot.com) - This widget is touch sensitive. It is able to trigger actions as the start and end of pans. Multiple differntial pans are possible.
[Persistent-states](https://wikilabs.github.io/#persistent-states) and [Remove-states](https://wikilabs.github.io/#remove-states)
[pick Plugin](https://skeeve.github.io/tw5-plugins/) - The pick plugin is a set of two filters and one widget to help extracting data from your TiddlyWiki file.
[PluginSize](https://tid.li/tw5/plugins.html#%24%3A%2Fplugins%2Ftelmiger%2FPluginSize:%24%3A%2Fplugins%2Ftelmiger%2FPluginSize) - This plugin calculates the size of all installed plugins, including themes and languages.
[PluginDevelopment](https://github.com/inmysocks/PluginDevelopment) – Scripts to help you create plugins and plugin libraries for node.js
[pv5](http://pv5.tiddlyspot.com/) - testing params and variables
[random (tobibeer)](http://tobibeer.github.io/tw5-plugins/#random) - A filter to return one or more random titles
[ReplacePragma](http://tiddlystuff.tiddlyspot.com/)
[Save trail plugin](https://tiddlywiki.com/#OfficialPlugins) - This plugin causes TiddlyWiki to continuously download (as a JSON file) the contents of any tiddler that is manually changed by any of several means **(official TW plugin)**
[setvars (tobibeer)](http://tobibeer.github.io/tw5-plugins/#setvars) - Set multiple, complex variables based on attributes, filters, or conditionals
[Shuffle filter operator](https://mklauber.github.io/tw5-plugins/#Shuffle%20Operator) - implements a new filter operator called Shuffle. This operator takes the input list and randomizes the order of the list. If no parameter is provided, the list order is random every time.
[SPilot4Tw](https://www.quaraman.de/tw/pilot.html) - A programming language that can be included as Tiddlywiki plugin.
[Startup Actions demo](http://ooktech.com/jed/ExampleWikis/StartupActions/) - A plugin to add startup scripts to TiddlyWiki
[style (tobibeer)](http://tobibeer.github.io/tw/style/#GettingStarted) - This wiki introduces you to using your desktop browser to inspect the styles applied to elements in TiddlyWiki and permanently change them.
[Three.js](http://rboue.tiddlyspot.com/#Three.js%2Fintroduction) - 3D modeling
[TiddlyWiki5 Coding](http://cjhunt.github.io/) - These pages document aspects TiddlyWiki5 programming, sharing "lessons learned" to help developers to get started with TiddlyWiki5 customization and extension. (FYI - 4 years old)
[Tinka](https://tinkaplugin.github.io/) - Create and modify plugins in the browser.
[Trace-variable example](http://eucaly-tw5.tiddlyspot.com/#trace-variable%20Example) - no clue what this is.
[Trigger Actions Demo](http://ooktech.com/jed/ExampleWikis/TriggerActions/)
[Tutorial Maker with HopScotchjs](https://cdn.rawgit.com/abesamma/TW5-tutorial-maker-plugin/29c31124/Demo.html) - a plugin that allows TW5 developers to create interactive product tutorials for their tiddlywiki projects, to guide new users.
[TW Components](https://tw-scripts.github.io/TW-Components/) - A component is a group of TW macros and tiddlers create a visual element for complex processes. The ultimate objective of TW components is to create objects which can simply by used by TW programmer to create complex plugins or codes.
[twexe - run exe's from hta files](https://github.com/welford/twexe) - only works in offline hta versions of TW. It lets you register and run exes from tiddlywiki

TiddlyWiki\Recently Changed Cards

8th January 2021 at 8:59am
CodeLibrary Filter TWCard
<<timeline limit:30 format:"YYYY-0MM-0DD">>

TiddlyWiki\Regular Expression

8th January 2021 at 8:59am
Filter Text TWCard
<!--|v
Split at Regular Expression skips everything before the first period -> `.12`,  `.1` and `.or.maybe.1`
^|-->

<$vars re="^[^\.]*">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>

<!--|v
Split at Regular Expression skips everything before the last period -> `1`,  `1` and `1`

Each:Value gets the unique list of entries -> `2` and `1`

Sort orders them numberically
^|-->

<$vars re="^.*\.">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>!match[]each:value[]sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>


<!--|v
Split
^|-->

<!--<$vars re="^[^\.]*"> skip up to first period excluded-->
<!--<$vars re="^.*\."> skip up to first period included-->
<$vars card_pk="File List Data" re="^.*\.">
<$list variable="cur_file_ext" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.gif(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.jpeg(?i)]] [<card_pk>get[text]splitregexp[\n]regexp[\.jpg$(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.png(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.tif(?i)]] +[splitregexp<re>!match[]each:value[]sort[]addprefix[.]]">
<$list variable="file_ext_count" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]suffix<cur_file_ext>count[]]">

<<cur_file_ext>>: <<file_ext_count>> files
</$list><!--file_ext_count-->
</$list><!--cur_file_ext-->
</$vars>

TiddlyWiki\Reveal Section and Copy Data

8th January 2021 at 8:59am
AssignVariable Formatting Text TWCard

Title = mcr T1Reveal

\define t1cb(UrContent)
<$list filter="[[$UrContent$]!match[]]">
$UrContent$
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
\end
\define t1reveal(UrPK UrSeq UrContent)
<$list filter="[[$UrContent$]!match[]]">
<br>
<$reveal type="nomatch" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="show">,,$UrSeq$,,</$button>
</$reveal>
<$reveal type="match" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="hide">^^$UrSeq$^^</$button><br>
"""
$UrContent$
"""
</$reveal>
<$list filter="[[$UrSeq$]match[Pwd]]">
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
</$list>
\end

TiddlyWiki\Save Wiki and Export HTML

8th January 2021 at 8:57am
Browser CodeLibrary Extract TWCard
\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.htm"
/>
<$action-sendmessage $message="tm-download-file"
$param="$:/core/templates/exporters/StaticRiver" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
exportFilter="""[all[tiddlers]tag[INDEX]sort[title]][all[tiddlers]!tag[EXTLINK]!tag[INDEX]!tag[META]!prefix[Draft of]!is[image]!is[tag]!is[system]sort[title]]"""/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.htm]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>

TiddlyWiki\Search all Fields

8th January 2021 at 8:57am
Filter Text TWCard
<$vars search_text_pk="$:/state/popup/SearchAllFields">
<$list variable=show_code_pk filter="[<search_text_pk>addsuffix[-checkShowCode]]">
<$list variable=skip_system_pk filter="[<search_text_pk>addsuffix[-checkSkipSystem]]">
<$edit-text tiddler=<<search_text_pk>> field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler=<<skip_system_pk>>> Skip System </$checkbox><br>
<br>

<$list variable=cur_search_text filter="[<search_text_pk>get[text]addsuffix[(?i)]!match[]]">
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]else[no]]">
<$list variable=cur_skipsystem_text filter="[<skip_system_pk>get[text]else[yes]match[yes]count[]]">

<!--Card titles-->
<$list variable=cur_pk filter="[regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_skipsystem_text>] [<cur_pk>!is[system]count[]] +[sum[]match[1]]">

<$link to=<<cur_pk>> />: title
</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

<!--Card fields-->
<$list variable=cur_pk filter="[!regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_pk>is[system]count[]multiply<cur_skipsystem_text>match[0]]">
<$list variable=cur_field filter="[<cur_pk>fields[]]">
<$list variable=found_field filter="[<cur_pk>get<cur_field>regexp<cur_search_text>]">

<$link to=<<cur_pk>> />: <<cur_field>>
<$list variable=disp_code filter="[<cur_showcode_text>match[yes]]">
<$codeblock code=<<found_field>> />
</$list><!--disp_code-->
</$list><!--found_field-->
</$list><!--cur_field-->

</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

</$list><!--cur_skipsystem_text-->
</$list><!--cur_showcode_text-->
</$list><!--cur_search_text-->
</$list><!--skip_system_pk-->
</$list><!--show_code_pk-->
</$vars><!--search_text_pk-->

TiddlyWiki\Section Display

8th January 2021 at 8:56am
Formatting Text TWCard

Card name = mcr glbl_section_disp

Tag = $:/tags/Macro

\define glbl_section_disp(ur_title, ur_section_num)
<$reveal type="nomatch" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="show">

!!$ur_title$ - Show
</$button></$reveal>
<$reveal type="match" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">

!!$ur_title$
</$button><br>

<<section$ur_section_num$>>

<$button style="float:right" class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">
---
</$button><br>
</$reveal>
\end
<!--|v
-- Card content call

\define section1()

section content

!!!here

\end
<<glbl_section_disp "Section 1" 1>>
^|-->

TiddlyWiki\Source Code Samples

8th January 2021 at 8:56am
CodeLibrary TWCard

TiddlyWiki Git repository sample code

[Home button] Tiddly Wiki Home Button source code

->

{{$:/core/images/home-button}}

[Save button] TiddlyWiki Save Button source code

->

<$action-sendmessage $message="tm-save-wiki" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>
  • This code says I can specify my own download file name
<span class="tc-dirty-indicator">
  • This code changes the color of elements within the <span> to red when the Wiki file has not been saved

[TiddlyWiki TopBar Menu]

TiddlyWiki TopBar Menu

->

<$button set="$:/state/sidebar" setTo="no"/>
<$button set="$:/state/sidebar" setTo="yes"/>
  • These lines show that the $:/state/sidebar Card is "no" to hide the sidebar, or "yes" show it

TiddlyWiki\Split Lines into Storage

8th January 2021 at 8:56am
AssignVariable Text TWCard
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>fields:exclude[created title modified]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<new_line_pk>> $field=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:25px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Temp Table

8th January 2021 at 8:55am
AssignVariable CodeLibrary TWCard
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>indexes[]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<ttbLINE>> $index=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:200px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$link to=<<ttbLINE>> />
<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Text Differences

8th January 2021 at 8:55am
Extract Text TWCard
<$diff-text source={{FirstTiddler}} dest={{SecondTiddler}}/>

TiddlyWiki\Textbox field

8th January 2021 at 8:55am
AssignVariable TWCard

You can choose to edit a Card or a Card's field in a single-line or multi-line textbox.

  • The default parameter is automatically placed in the textbox when the Card does not exist
    • Typing in the box will add to the default text
    • The Card will be created when the text in the box is changed
    • Otherwise the default text will not be saved
  • The placeholder parameter is shown as greyed-out text when the Card does not exist and there is no default text, or the Card exists and the text field is empty
    • Typing in the box will overwrite the placeholder text

Note: Editing a Card PK that starts with $:/state/popup/ will not be saved and does not affect the Wiki's "dirty" flag

$:/state/popup/TestText1

<$edit-text tiddler="$:/state/popup/TestText1" field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>


$:/state/popup/TestText2

<$edit-text tiddler="$:/state/popup/TestText2" field=text default="here" placeholder="[no text yet]" autoHeight=yes tag=textarea/>

TiddlyWiki\TiddlySaver from Downloads

8th January 2021 at 10:54am
FileSystem TWCard WindowsOS

Make a small form with a timer that moves downloaded TiddlyWiki files back to their original folder

- I have not tried to play around with running TW5 on Node.js. I don't prefer having to use TiddlyDesktop as a separate web browser. Installing a plugin would only save my wiki changes under the downloads directory. I like using a portable web browser on my thumb drive, and I am able to run non-admin programs on my computer. So I made a small program with a timer to move each saved TW file from my Downloads directory back to its original loading location.

- I leave the program running all the time I am logged in. Alt-S saves the data in TiddlyWiki to the Downloads folder. After at most five seconds, the timer moves the file to overwrite the original location. The form flashes on the screen for one second and then hides itself until another move.

1) I created an alt-S shortcut macro to save the current wiki with a specific filename prefix (TWMove_), the entire file path - with substitutions for path-specific characters (: and \), and a time stamp. (Using split/join is accurate enough for me.)

Example: TWMove_C-colon-slash-RootDirOne-slash-SubDirTwo-slash-UrWiki.html


\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.html]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>

2) I have my web browser save all downloaded files to a specific Downloads folder. (Specifically on Google Chrome, I did install a plugin to automatically hide the dowloaded files bar. It was getting annoying.)

3) I created a small program with a multi-line textbox, and a timer to poll the Downloads folder every five seconds. It moves all the TWMove files in alphabetical order, so the latest timestamped file will be processed last. It finds the destination path as part of the filename. (Moving assumes the original TW.html file is not locked by the browser. This happened to me once, but I just had to restart the browser to release the file lock.)

The program's text box shows the folder I'm polling. When it picks up a file, the original path is pre-pended to the textbox's list of processed files and the form flashes in the foreground for a second. (I could have made a system tray pop-up notification instead.)

It's not perfect, but definitely doable for most amateur programmers.

TiddlyWiki\Transclude Card Field

8th January 2021 at 8:54am
Extract Text TWCard
<$transclude mode="block" tiddler=<<currentTiddler>> />

<$transclude mode="inline" tiddler=<<currentTiddler>> field="ref_data" />

TiddlyWiki\Unicode Character List

8th January 2021 at 8:51am
CodeLibrary TWCard Unicode
\define CharRef(ur_code, ur_line_grouping)
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]floor[]] " variable=div_val>
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]match<div_val>] "><br><sub>$ur_code$
<<glbl_dec_to_hex5 "$ur_code$">>
</sub><br>
</$list>
</$list>
[&#$ur_code$;]
\end

https://en.wikipedia.org/wiki/Unicode_block

https://en.wikipedia.org/wiki/Plane_(Unicode)


<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text=""/>
Line Grouping = 10
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text="16"/>
Line Grouping = 16
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text=""/>
Clear selection
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="0"/>
Show Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="65536"/>
Show Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="131072"/>
Show Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="196608"/>
Show Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)
</$button>

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

@@font-family: "Lucida Console", Courier, monospace;
<$list filter="[{$:/state/mcr CharRef LineGrouping}!match[]else[10]] " variable=line_grouping>
<$list filter="[[$:/state/mcr CharRef CharacterListBase]get[text]!match[]]">
<$list filter="[range[512]subtract[1]multiply[128]add{$:/state/mcr CharRef CharacterListBase}]" variable=cur_block>
<h2><<cur_block>></h2>
<$list filter="[range[128]subtract[1]] +[add<cur_block>] " variable=cur_code>
<$macrocall $name=CharRef ur_code=<<cur_code>> ur_line_grouping=<<line_grouping>> />
</$list>
</$list>
</$list>
</$list>

TiddlyWiki\Unicode Codepoints Used

8th January 2021 at 8:51am
Extract TWCard Unicode
\define dec_to_u_hex4()
<$list variable=cur_d4 filter="[[$(dec_num)$]divide[16]floor[]divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d4 filter="[[0]subtract<cur_d4>multiply[16]multiply[16]multiply[16]add[$(dec_num)$]]"
><$list variable=cur_d3 filter="[<rem_d4>divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d3 filter="[[0]subtract<cur_d3>multiply[16]multiply[16]add<rem_d4>]"
><$list variable=cur_d2 filter="[<rem_d3>divide[16]floor[]]"
><$list variable=rem_d2 filter="[[0]subtract<cur_d2>multiply[16]add<rem_d3>]"
><$list variable=hex filter="[[;]addsuffix<cur_d4>addsuffix[;]addsuffix<cur_d3>addsuffix[;]addsuffix<cur_d2>addsuffix[;]addsuffix<rem_d2>split[;10]join[A]split[;11]join[B]split[;12]join[C]split[;13]join[D]split[;14]join[E]split[;15]join[F]split[;]join[]]"
>\u<<hex>></$list><!--hex
--></$list><!--rem_d2
--></$list><!--cur_d2
--></$list><!--rem_d3
--></$list><!--cur_d3
--></$list><!--rem_d3
--></$list><!--cur_d4
-->
\end
\define entry_hexcode(ur_char, ur_code_page)
<$list variable=cur_codepage filter="""[[$ur_code_page$]!match[]else[0]multiply[256]]""">
<$list variable=dec_num filter="""[range[256]add<cur_codepage>]""">
<$wikify name=hex_unicode text=<<dec_to_u_hex4>> >
<$list filter="""[[$ur_char$]regexp<hex_unicode>]""" variable=match_text>
-$ur_char$-<<hex_unicode>>-&amp;#<<dec_num>>;
</$list><!--match_text-->
</$wikify><!--hex_unicode-->
</$list><!--cur_unicode-->
</$list><!--cur_unicode-->
\end
\define unicode_points(ur_pk)
<$list variable=code_page filter="[[$:/state/unicode_points_codepage]get[text]else[0]]">

Code page = <<code_page>> <$button

style="margin-left:30px">
<$list variable="next_page" filter="[<code_page>add[1]]"><$action-setfield $tiddler="$:/state/unicode_points_codepage" text=<<next_page>>/></$list>
Next page
</$button><$button

style="margin-left:30px">
<$action-setfield $tiddler="$:/state/unicode_points_codepage" text="0"/>
Reset
</$button><br>


<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]count[]!match[1]!match[0]]">-&#x005D;-\u005D-&amp;#93;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u0060]count[]!match[1]!match[0]]">-&#x0060;-\u0060-&amp;#96;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]join[]splitregexp[\u0060]join[]split[]each:value[]sort[]]">-<<cur_char>>-
<$macrocall $name=entry_hexcode ur_code_page=<<code_page>> ur_char=<<cur_char>> />
<br>
<br>
</$list><!--cur_char-->
</$list><!--code_page-->
\end

<<unicode_points "UrPK">>

TiddlyWiki\Upload File

8th January 2021 at 8:50am
Extract FileSystem TWCard

Drag and drop

  • Drag a file icon from the Windows Desktop or Windows Explorer over the Wiki until you see a top-margin green bar show
  • Release the mouse to drop the file -> Opens card

Import Card

  • Review the file list and uncheck and undesired import objects
  • Click button Import -> Creates Cards

BrowseWidget

  • Create a $browse tag -> Makes button
  • Click button Choose File -> Opens dialog
  • Choose a file -> Closes dialog, opens Card

Import Card

  • Review the file list and uncheck and undesired import objects
  • Click button Import -> Creates Cards
<$browse />

TiddlyWiki\Video and Audio

8th January 2021 at 8:50am
Audio TWCard Video
  • Title = mcr glbl_ext_av
  • Tag = $:/tags/Macro
  • Note: The paths are relative to the current website. You cannot load Video or Audio content from other websites due to browser restrictions.
  • Note: You can add attribute poster="placeholder.png" to the Video tag if you have a specific image you want instead of the video's first frame
\define glbl_ext_video(UrFolder,UrVideo,UrTime)
<video width="320" height="180"
controls preload="metadata">
<source src="$UrFolder$/$UrVideo$.mp4#t=$UrTime$" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
\end
\define glbl_ext_audio(UrFolder,UrAudio,UrTime)
<audio controls preload="none">
<source src="$UrFolder$/$UrAudio$.mp3#t=$UrTime$" type=
"audio/mp3">
Your browser does not support the HTML 5 audio tag.
</audio>
\end

<!--|v
* Hard-coded to only use MP4 files

<<glbl_ext_video "MyVideosSubFolder" "MyVideoFile" "00:01:00">>

<<glbl_ext_video "file:///C:/UrFolder/UrSubFolder" "UrFilenameNoExtension" "00:01:00">>
^|-->
<!--|v
<<glbl_ext_audio "MyAudioSubFolder" "MyAudioFile" "00:01:00">>
^|-->

TiddlyWiki\View All Cards

8th January 2021 at 8:49am
CodeLibrary Extract TWCard
<$list filter="[all[tiddlers]!tag[EXTLINK]!tag[IMG]!tag[INDEX]!tag[MCR]!tag[META]!has[draft.of]!is[image]!is[tag]!is[system]has[tags]!prefix[undefined]sort[title]]">
<hr>
<h2><$link to=<<currentTiddler>> /></h2>
{{||$:/core/ui/ViewTemplate/tags}}
<$transclude mode="block"/>
</$list>

TiddlyWiki\Wikify Text

8th January 2021 at 8:45am
Extract Text TWCard
<$wikify name=str_text_out text="&#65;">
A = <<str_text_out>>
</$wikify>

<$wikify name=str_text_out text="''bold font''" output=html>
B = <<str_text_out>>
</$wikify>

TiddlyWiki\WikiText Formatting

8th January 2021 at 8:46am
CodeLibrary Formatting Text TWCard

You can type most standard text without problems. Leading, repeated, or paired special characters may need escaped.

Vertical Spacing

Pressing enter at the end of a line does not start a new paragraph.
Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph.
Press enter twice.

For example, see how the above two paragraphs are shown below:

Pressing enter at the end of a line does not start a new paragraph. Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph. Press enter twice.

Leading Special Characters

Bulleted List Entry

*Bulleted List Entry
  • Bulleted List Entry

Leading with an asterisk creates a bulleted list entry. To escape, prefix with four single-quotes.

If you want a single blank line between two bullet points, use a !! Heading Line without any title text.

''''*Bulleted List Entry

*Bulleted List Entry

Heading Line

!Heading Line

Starting a new paragraph line with an exclamation mark (!) results in a heading line.

!Heading Line

The above heading markup starts with an exclamation mark. To escape, prefix with four single-quotes.

''''!Heading Line

!Heading Line

Mono-spaced Text Block

 ```
 Mono-spaced Text Block
 ```
Mono-spaced Text Block

Leading with a triple back-tick creates a mono-space text block. To escape, surround the triple back-tick with doubled square-brackets.

[[''']] Regular typeface

``` Regular typeface

Numbered List Entry

#Numbered List Entry
  1. Numbered List Entry

Leading with a pound-sign creates a numbered list entry. To escape, prefix with four single-quotes.

''''#Numbered List Entry

#Numbered List Entry

Quoted text block

<<<
Quoted text block
<<<

Quoted text block

Leading with a triple less-than creates a quoted text block. To escape, surround the

''''<<< Unquoted text

<<< Unquoted text

URL Links

https://tiddlywiki.com/

https://tiddlywiki.com/

Start text with an "http://" "http://" will create a URL link. To escape, place four single-quotes before the colon and between the double forward-slashes.

https'''':/''''/tiddlywiki.com/

https://tiddlywiki.com/

Repeated Special Characters

''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`

Bold Text Italic Text Strike-through Text Underlined Text Raised-Small Text Lowered-Small Text Mono-spaced Text

A number of repeated special characters are used as Wiki Markup to format text. To escape, place four single-quotes between the doubled characters or surround the doubled characters with doubled square-braces.

[['']]Bold Text[['']] /''''/Italic Text/''''/ ~''''~Strike-through Text~''''~ _''''_Underlined Text_''''_ ^''''^Raised-Small Text^''''^ ,'''',Lowered-Small Text,'''', [[`]]Mono-spaced Text[[`]]

''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`

Paired Special Characters

Literal Text

[[Literal Text]]

Literal Text

Surrounding text with doubled square-brackets shows the literal surrounded text without applying formatting. To escape, place four single-quotes between the first doubled square-brackets.

[''''[Literal Text]]

[[Literal Text]]

Transcluded Text

{{Other Tiddler Title}}

Note: The other tidder's content is "Other Tiddler Transcluded Text".

Surrounding text with doubled curly-braces shows the full content of another tiddler. To escape, place four single-quotes between the first doubled curly-braces.

{''''{Other Tiddler Title}}

{{Other Tiddler Title}}

HTML Markup

<b>HTML Markup</b>

HTML Markup

Surrounding text with angled-brackets uses HTML formatting. To escape, rename the first angle-bracket to &lt;

&lt;b>HTML Markup</b>

<b>HTML Markup</b>

HTML Literals

&lt;

Note: &lt; represents a left angle-bracket, or the less-than symbol (<).

<

Surrounding text with an ampersand (&) and a semi-colon translate to an HTML literal. To escape, place four single-quotes after the ampersand.

&lt;

&lt;

CSS Styles

You can apply CSS styles in-line with the text. Make sure you put the semi-colon at the end of the style list.

You can apply @@background-color:yellow; CSS styles @@ in-line with the text.

You can apply CSS styles in-line with the text.

Tables

|!Cell1 |!Cell2 |
|Cell3 |Cell3 |

|^top left |^ top center |^ top right|
|middle left | middle center | middle right|
|,bottom left |, bottom center |, bottom right|


To merge a table cell with the one above, use the special cell text ~. To merge a cell with the one to its left use the text <. To merge one to its right use >. For example:

|Cell1 |Cell2 |Cell3 |Cell4 |
|Cell5 |Cell6 |Cell7 |<|
|Cell5 |~|Cell7 |Cell8 |
|>|Cell9 |Cell10 |Cell11 |

assigns the CSS classes "myclass" and "anotherClass" to the table
gives the table the caption "This is a caption"
adds a header row of cells with the text "Header"
adds a footer row of cells with the text "Footer"
|myclass anotherClass|k
|This is a caption |c
|Cell1 |Cell2 |
|Cell3 |Cell3 |
|Header|Header|h
|Footer|Footer|f

TiddlyWiki\Word Wrap

8th January 2021 at 1:27am
Text TWCard WordWrap

Hard-line breaks using CSS styles

.tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
  • Note: When using this alternate CSS, wiki text markup will be ignored unless preceded by a double-spaced line
  • Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

Sample Code:

*bullet 1
*bullet 2
*bullet 3
Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a ",,,,",,,," wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

*bullet 4 requires a preceding double-spaced line to be interpreted as wikitext

Results:

* bullet 1
* bullet 2
* bullet 3

Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a """ wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

* bullet 4 requires a preceding double-spaced line to be interpreted as wikitext

Apply stylesheet to cards with specific tag linewrap

[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}

Apply Styles to In-line Text

  • Start a text block with @@ and the CSS styles with no spaces

Sample Code:

@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line

Result:

These are
separate lines
here

This is one big line
  • or start in the middle of a text block

Sample Code:

This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.

Result:

This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.

TotalCommander

25th December 2020 at 10:51pm
DOC

TotalCommander\Create new Text File

8th January 2021 at 10:59am
AndroidOS FileSystem Text

[Total Commander directory]
- [Top of the directory]
- Hold down on the '..' button to see the menu -> Opens menu
- - or Hold down on any subdirectory name to see the menu -> Opens menu

- [context menu]
- Click option New Text file -> Opens dialog

- [Create new text file dialog]
- Enter a new text file name
- Click button OK -> Closes dialog

- [Directory list]
- Note: The new file was added to the current folder

TotalCommander\Local file desktop shortcut

8th January 2021 at 10:58am
AndroidOS AssignVariable FileSystem

Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Total Commander directory]
- Hold down on file entry named like *.html -> Opens menu

- [context menu]
- Click option Create link on desktop -> Opens dialog

- [Create link dialog, main page, command line section]
- Click button '>>' -> Opens dialog

- [Choose app dialog, main page]
- Click option Choose app * -> Navigates page

- [Choose app dialog, Choose app * page]
- Click option Chrome -> Navigates page

- [Create link dialog, main page]
- Click button OK / Apply -> Closes dialog

[Android Desktop icons]
- Note: The icon was added to the desktop automatically

TW Project

13th January 2021 at 7:29am
DOC

TW Project\Check app

9th February 2021 at 7:39pm
CodeLibrary TWCard

Project Check app

->

Goal: Find food by aisle

TW Project\Code Snapshot

6th March 2021 at 8:22pm
CodeLibrary TWCard

TW Project\Features list

13th January 2021 at 7:24am
CodeLibrary TWCard

TW Features

->

Goal: Demonstrate every Wiki command and option

TW Project\Javascript Plugin instructions

13th January 2021 at 7:29am
JavaScriptCode TWCard

TW Project\Shuffle List addon

13th January 2021 at 7:26am
CodeLibrary Filter TWCard

TW Project\Text Replace addon

13th January 2021 at 7:23am
AssignVariable Text TWCard

TW Addon Text Replace

->

Goal: Add text replacement functionality to the standard TWCard editor

TW Project\TiddlyWiki Manual

13th January 2021 at 7:25am
CodeLibrary TWCard

TW Manual

->

Goal: Explain the Single-Page Quine Wiki architecture

TW Project\TW JS Pretty

13th January 2021 at 7:30am
Formatting JavaScriptCode TWCard

TW JS Pretty

->

Goal: Upload a text file and comment on each line, table or function

TW Project\Wiki Empty Setup

6th March 2021 at 9:25pm
Extract HTMLCode TWCard

Empty Wiki Setup

->

Goal: Use the empty TW document and generate a static HTML page

Unicode\Code Blocks

8th January 2021 at 8:43am
CodeLibrary Text Unicode

Unicode Block 00-Basic Latin

->

Unicode Block 01-Latin Supplement

->

Unicode Code Block List

->

Unicode Block Planes

->

Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)

Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)

Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)

Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

Unicode\Latest Version

8th January 2021 at 8:39am
CodeLibrary Text Unicode

Unicode Character Database

->

All files for the most up-to-date version of the Unicode Character Database can be found at: http://www.unicode.org/Public/UCD/latest/.

The latest text file databases are at https://www.unicode.org/Public/UCD/latest/ucd/. The latest set of text file databases is in a ZIP file at https://www.unicode.org/Public/UCD/latest/ucd/UCD.zip.

The list of Unicode Code Blocks are in the text database https://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt.

There is a list of names for the Unicode Code Points at https://www.unicode.org/Public/UCD/latest/ucd/Index.txt. There same list is sorted in Code Point order at https://www.unicode.org/Public/UCD/latest/ucd/NameAliases.txt. Each hex code can have multiple names.

The unique list of Unicode Code Points is at https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt. There is a character name and possibly an alternative name on each row.

VBNetCode

25th December 2020 at 10:51pm
DOC

VBNetCode\Application Startup require DLLs

8th January 2021 at 10:53am
CodeLibrary VBCode
Option Strict On
Namespace My
    Partial Friend Class MyApplication
        Sub Main(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
            Mx.Want.TestReferencedAssemblies_errhnd(e)
            'Next goes to frmInput_1_Load, then Want.Compile_And_Run_Script
        End Sub
    End Class
End Namespace

Namespace Mx
    Partial Public Class Want
        Public Shared Sub TestReferencedAssemblies_errhnd(ur_startup_event_args As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs)
            Dim objERR_LIST = New ErrListBase : Try
                Call Assistant.TestReferencedAssemblies()

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                MsgBox(objERR_LIST.ToString, , My.Application.Info.Title)
                ur_startup_event_args.Cancel = True
            End If
        End Sub 'TestReferencedAssemblies_errhnd
    End Class 'Want
    
    Partial Public Class Assistant
        Public Shared Sub TestReferencedAssemblies()
            'Will error if DLL does is not available
            Dim objV1 = System.Data.SqlClient.SortOrder.Ascending
        End Sub 'TestReferencedAssemblies
    End Class 'Assistant
End Namespace 'Mx

VBNetCode\Checksum calculate

8th January 2021 at 10:53am
Extract Numbers VBCode

I want a .Net program to calculate the SHA512 hash of a file

Dim strHASH_KEY = ""
Using objSHA = New System.Security.Cryptography.SHA512Managed
    Using stmFILE = System.IO.File.OpenRead(flnDATA)
        strHASH_KEY = "[" & System.BitConverter.ToString(objSHA.ComputeHash(stmFILE)).Replace("-", "").ToLower & "]"
        'Convert.ToBase64String(
    End Using
End Using

VBNetCode\Copy File Lines

8th January 2021 at 10:53am
Extract FileSystem VBCode
Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), bolAPPEND_FILE, gUTF8_FileEncoding)
	Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
		While stmDATA.EndOfStream = False
			'Character copy
			Dim intENTRY = stmDATA.Read()
			Dim strENTRY = ChrW(intENTRY)
			stmOUT_FILE.Write(strENTRY)
			
			'Line copy
			Dim strLINE = stmDATA.ReadLine()
			stmOUT_FILE.WriteLine(strLINE)
		End While 'stmDATA
	End Using 'stmDATA
End Using 'stmOUT_FILE

Split File into chunks of 100,000 lines each

Dim intFILE_COUNT = 0
Dim intLINE_COUNT = 0
Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
	While stmDATA.EndOfStream = False
		intFILE_COUNT += 1
		intLINE_COUNT = 0
		Dim strFILE_COUNT = intFILE_COUNT.ToString()
		If Len(strFILE_COUNT) = 2 Then
			strFILE_COUNT = "c" & strFILE_COUNT
		ElseIf Len(strFILE_COUNT) = 3 Then
			strFILE_COUNT = "d" & strFILE_COUNT
			
			End If 'strFILE_COUNT
		
		strFILE_COUNT = "e" & strFILE_COUNT
		Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT(strFILE_COUNT & ".TXT"), False, gUTF8_FileEncoding)
			While stmDATA.EndOfStream = False
				Dim strLINE = stmDATA.ReadLine()
				stmOUT_FILE.WriteLine(strLINE)
				intLINE_COUNT += 1
				
				If intLINE_COUNT >= 100000 Then
					Exit While
					
					End If
				
				End While 'stmDATA
			
			End Using 'stmOUT_FILE

		End While 'stmDATA
	
	End Using 'stmDATA

VBNetCode\DotNet Core Compile EXE

8th January 2021 at 10:54am
Extract VBCode WindowsOS

[https://github.com/dotnet/core/issues/5409]

In .NET 5 the single-file publish may produce more than one file and it's by design. See the expected behavior described here:

https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md#user-experience

In 3.1 single-file is basically just a self-extracting executable - it writes everything into temp and runs from there. As such for the running app nothing really changes (everything is a file, with a path and so on).

In 5 we don't write to disk by default, all managed assemblies are loaded directly from the executable. The problem is native libraries - it's technically VERY difficult to include a random .dll in an executable and run it from the executable directly.

If you only take the .exe and run it, it won't work - it needs those additional files.

If you need .NET 5 but want the self-extracting behavior you can set IncludeAllContentForSelfExtract=true and it will behave basically the same as in 3.1.

There's also a "hybrid" mode IncludeNativeLibrariesForSelfExtract=true which will produce just one executable and that will write the native libraries to temp and then run.

User-replaced value = UrProjectDir

[UrProjectDir folder] - Start with VBNetCode\DotNet Core New Project

[Windows CLI]
- [Compile into an EXE]
- dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep
- Text output ->

Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  t3 -> UrProjectDir\bin\Release\net5.0\win10-x64\UrProjectDir.dll
  t3 -> UrProjectDir\Dep\

[UrProjectDir folder]
- [Look for the new folders]
- New sub-folders: bin, Dep
- Note: The compiled program is in the Dep subfolder named UrProjectDir.exe
- - The UrProjectDir.pdb file is used for debugging purposes and would not normally be deployed with your EXE file

[Windows CLI]
- [Remove the temporary folders in the UrProjectDir]
- rd bin /s /q
- rd obj /s /q
- [Run the project]
- Dep\UrProjectDir.exe
- Text output shows as if you ran the command dotnet run

- Note: You can output the System.AppContext.BaseDirectory to find the Temp that holds the uncompressed program

[Program.vb file]
- [Replaces lines in Main sub]
- Console.WriteLine(System.AppContext.BaseDirectory)

[Windows CLI]
- [Compile into an EXE]
- dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep
- Note: If running DotNet Core 3.1,
- - dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true -p:PublishSingleFile=true
- - The "–self-contained" option is incompatible with the "-p:PublishReadyToRun=true" and "-p:PublishSingleFile=true" options

- Note: When you choose the Portable publish option, you'll get a package that is capable of running on either x86 (32-bit) machines and x64 (64-bit) machines
- - The next run would have to JIT compile the application again as it is used
- - The advantage here is that you'd only need to distribute one package, and it'll run on both x86/x64 machines
- - dotnet publish -c Release -r portable --self-contained

- [Remove the temporary folders in the UrProjectDir]
- rd bin /s /q
- rd obj /s /q
- [Run the project]
- Dep\UrProjectDir.exe
- Text output =

C:\Users\UrUsername\AppData\Local\Temp\.net\UrProjectDir\SomeRandom-8-letters.SomeRandom-3-letters\

- Note: This folder gets created on the first run the of UrProjectDir.exe
- - The second run starts faster because the files have already been extracted to this temporary folder
- - You can delete the temporary folder, and running the UrProjectDir.exe will create it again.

- Note: You can specify a different temporary folder by setting the Environment Variable DOTNET_BUNDLE_EXTRACT_BASE_DIR

- SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%USERPROFILE%\Downloads\UrProjectDir\tmp
- Note: You can set the Environment Variable in a batch file and it will not be saved for new Windows CLI windows.
- - To set it permanently, use Control Panel \ System and Security \ System \ Advanced systems settings \ Advanced tab \ Environment Variables button \ top or bottom section \ New button, Variable Name = DOTNET_BUNDLE_EXTRACT_BASE_DIR, Variable Value = UrFullPathToTempDirectory, OK button
- - Trying to use a relative directory path ends up not running the executable

- [Run the project]
- Dep\UrProjectDir.exe
- Text output =

C:\Users\UrUsername\Downloads\UrProjectFolder\tmp\UrProjectFolder\SomeRandom-8-letters.SomeRandom-3-letters\

- [Review the size of the TMP folder]
- dir tmp /s
- Text output = 23 Files, 8 Dirs

- [Remove the temporary directory]
- rd tmp /s /q

[UrProjectDir\Dep folder]
- [Create a script to run the project and clean up the temporary files]
- New file = UrProjectDir.cmd

[UrProjectDir.cmd file]

@@ECHO OFF
SET CUR_DIR=%~dp0
SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%CUR_DIR%tmp
"%CUR_DIR%UrProjectDir.exe"
rd "%CUR_DIR%bin" /s /q 2> nul
rd "%CUR_DIR%obj" /s /q 2> nul
rd "%CUR_DIR%tmp" /s /q 2> nul

[Windows CLI]
- [Run the clean-execution script]
- Dep\UrProjectDir.cmd
- Note: There is no tmp subfolder

VBNetCode\DotNet Core Installation using Binaries

8th January 2021 at 10:54am
VBCode WindowsOS

[https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net50]

As an alternative to the Windows installers for .NET, you can download and manually install the SDK or runtime. Manual install is usually performed as part of continuous integration testing. For a developer or user, it's generally better to use an installer.

Both .NET SDK and .NET Runtime can be manually installed after they've been downloaded. If you install .NET SDK, you don't need to install the corresponding runtime. First, download a binary release for either the SDK or the runtime from one of the following sites:

https://dotnet.microsoft.com/download/dotnet/5.0

https://dotnet.microsoft.com/download/dotnet-core

Create a directory to extract .NET to, for example %USERPROFILE%\dotnet. Then, extract the downloaded zip file into that directory.

By default, .NET CLI commands and apps won't use .NET installed in this way and you must explicitly choose to use it. To do so, change the environment variables with which an application is started:

set DOTNET_ROOT=%USERPROFILE%\dotnet
set PATH=%USERPROFILE%\dotnet;%PATH%
set DOTNET_MULTILEVEL_LOOKUP=0

This approach lets you install multiple versions into separate locations, then explicitly choose which install location an application should use by running the application with environment variables pointing at that location.

When DOTNET_MULTILEVEL_LOOKUP is set to 0, .NET ignores any globally installed .NET version. Remove that environment setting to let .NET consider the default global install location when selecting the best framework for running the application. The default is typically C:\Program Files\dotnet, which is where the installers install .NET.

[https://docs.microsoft.com/en-us/dotnet/core/install/how-to-detect-installed-versions?pivots=os-windows]

When you install .NET from an installer or script, it's installed to a standard folder. Much of the time the installer or script you're using to install .NET gives you an option to install to a different folder. If you choose to install to a different folder, adjust the start of the folder path.

dotnet executable in C:\program files\dotnet\dotnet.exe

.NET SDK in C:\program files\dotnet\sdk\{version}\

.NET Runtime in C:\program files\dotnet\shared\{runtime-type}\{version}\

VBNetCode\DotNet Core Installed Path

8th January 2021 at 10:52am
Extract FileSystem VBCode

[Windows CLI]
- [Run the system information report]
- dotnet --info

.NET Core SDK (reflecting any global.json):
 Version:   3.1.401
 Commit:    5b6f5e5005

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18363
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.401\

Host (useful for support):
  Version: 3.1.7
  Commit:  fcfdef8d6b

.NET Core SDKs installed:
  3.1.301 [C:\Program Files\dotnet\sdk]
  3.1.401 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download

VBNetCode\DotNet Core New Project

8th January 2021 at 10:51am
Extract VBCode

[https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new]

You can run dotnet new –list or dotnet new -l to see a list of all installed templates. If the TEMPLATE value isn't an exact match on text in the Templates or Short Name column from the returned table, a substring match is performed on those two columns.

Starting with .NET Core 3.0 SDK, the CLI searches for templates in NuGet.org when you invoke the dotnet new command in the following conditions:

  • If the CLI can't find a template match when invoking dotnet new, not even partial.
  • If there's a newer version of the template available. In this case, the project or artifact is created but the CLI warns you about an updated version of the template.

[https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli]

User-replaced value = UrProjectDir

[Windows CLI]
- [Navigate to the User Downloads folder]
- cd %USERPROFILE%\Downloads
- [Create a new DotNet Core project named UrProjectDir]
- dotnet new console -lang VB -o UrProjectDir
- Text output =

Getting ready...
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj...
  Determining projects to restore...
  Restored C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj (in 65 ms).
Restore succeeded.

- [Navigate to the new UrProjectDir]
- cd UrProjectDir

[UrProjectDir folder]
- [Look for the new files and folders]
- New files: UrProjectDir.vbproj and Program.vb
- New sub-folder: obj

[Windows CLI]
- [Download a dependency]
- dotnet add package Figgle
- Text output =

  Determining projects to restore...
  Writing C:\Users\Dad\AppData\Local\Temp\tmpE018.tmp
info : Adding PackageReference for package 'Figgle' into project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info :   GET https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json
info :   OK https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json 104ms
info : Restoring packages for C:\Users\Dad\Downloads\t3\t3.vbproj...

info : Installing runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple 4.3.0.
info : Installing runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl 4.3.0.

info : Package 'Figgle' is compatible with all the specified frameworks in project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : PackageReference for package 'Figgle' version '0.4.0' added to file 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : Committing restore...
info : Writing assets file to disk. Path: C:\Users\Dad\Downloads\t3\obj\project.assets.json
log  : Restored C:\Users\Dad\Downloads\t3\t3.vbproj (in 8.04 sec).

[Program.vb file]
- [Replace lines in Main sub]
- Console.WriteLine(Figgle.FiggleFonts.Standard.Render("Hello, World!"))

[Windows CLI]
- [Compile into an EXE and run it]
- dotnet run
- If you did not enter the program line incorrectly, Text output =

Program.vb(5,79): error BC30037: Character is not valid.

The build failed. Fix the build errors and run again.

- If you entered the program line correctly, Text output shows Hello World in a large font

VBNetCode\DotNetCore Installation using Installer

8th January 2021 at 10:54am
VBCode WindowsOS

[https://dotnet.microsoft.com/platform/support/policy/dotnet-core]
- 2020m11d24: .NET 5 is the current version of DotNet Core. It was released on November 10, 2020.

[https://dotnet.microsoft.com/download/dotnet-core]
- [Supported versions, record Version = .NET 5.0]
- Click link .NET 5.0 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/5.0]
- [record Release Information = v5.0.0, Build Apps column]
- [SDK grid, record OS = Windows]
- Click link x86 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-windows-x64-installer]
- Auto-download started -> Saves file

[Local Computer Downloads folder]
- [filename = dotnet-sdk-5.0.100-win-x64.exe]
- Run program -> Opens form

[Microsoft .NET SDK 5.0.100 (x64) Installer window]
- Click button Install -> Windows dialog
- Question: Do you want to allow the program to make changes to your computer?
- Click button Yes -> Closes dialog
- Wait for progress bar to complete -> Navigates page
- Note: Installation was successful
- Click button Close -> Closes window

VBNetCode\DotNet Core Installed Path

VBNetCode\File Exists

8th January 2021 at 10:51am
Extract FileSystem VBCode
Dim bolFILE_EXISTS = System.IO.File.Exists(flnDATA)

VBNetCode\File Size

8th January 2021 at 10:51am
Extract FileSystem VBCode
Dim sioFILE = New System.IO.FileInfo(flnDATA)
Dim intFILE_SIZE = sioFILE.Length

VBNetCode\Global functions passed as Classes

8th January 2021 at 10:51am
AssignVariable CodeLibrary VBCode
    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

VBNetCode\In-Memory Compile

8th January 2021 at 10:51am
CodeLibrary Extract VBCode
Namespace Mx
    Public Class ScriptRun
        ' Build a Hello World program graph using 
        ' System.CodeDom types.
        Public Class enmC_V_J
            Inherits bitBASE
            Public Shared CSharp As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared VisualBasic As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared JScript As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
        End Class 'enmC_V_J

        Public Shared Function RunCode(ur_provider As Mx.ScriptRun.enmC_V_J, ur_input_script As String, ur_assembly_folder As String) As String
            Dim strSOURCE_CODE = ur_input_script
            Dim stpERR_MSG = Strapd()
            Dim stpCODE_FILE = Strapd()
            ' Configure a CompilerParameters that links System.dll and produces the specified executable file.
            Dim objAPP_DOMAIN As AppDomain = Nothing
            Dim objCOMPILE_RUNNER As CompilerRunner = Nothing
            Dim objCOMPILER_PARM = New System.CodeDom.Compiler.CompilerParameters
            Dim objCOPMILER_RESULT As System.CodeDom.Compiler.CompilerResults = Nothing
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing

            If stpERR_MSG.Length = 0 Then
                'objAPP_DOMAIN = System.AppDomain.CreateDomain("MyDomain", AppDomain.CurrentDomain.Evidence, CreateSetup())
                'objCOMPILE_RUNNER = objAPP_DOMAIN.CreateInstanceFromAndUnwrap(GetType(CompilerRunner).Assembly.Location, GetType(CompilerRunner).FullName)
                objCOMPILE_RUNNER = New Mx.CompilerRunner
                stpERR_MSG.d(objCOMPILE_RUNNER.Compile(stpCODE_FILE.ToString, ur_provider.name, objCOMPILER_PARM))
            End If

            If stpERR_MSG.Length = 0 Then
                stpERR_MSG.d(objCOMPILE_RUNNER.Run("Mx.Class1", "RetVal"))
            End If

            If objAPP_DOMAIN IsNot Nothing Then
                'AppDomain.Unload(objAPP_DOMAIN)
            End If
            ' Return the results of compilation.
            Return stpERR_MSG.ToString
        End Function 'RunCode

        Public Shared Function CreateSetup() As AppDomainSetup
            Dim retSETUP = New AppDomainSetup
            With retSETUP
                .ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
                .ApplicationName = "TestDLL"
                .DisallowBindingRedirects = False
                .ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
                .LoaderOptimization = LoaderOptimization.MultiDomainHost
            End With
            CreateSetup = retSETUP
        End Function 'CreateSetup
    End Class 'ScriptRun

    Public Class CompilerRunner
        Inherits MarshalByRefObject

        Public cur_assembly As System.Reflection.Assembly = Nothing
        'AppDomain.CurrentDomain.FriendlyName = MyDomain

        Public Function Compile(ur_code As String, ur_provider As String, ur_compiler_parm As System.CodeDom.Compiler.CompilerParameters) As String
            Dim stpERR_MSG = Strapd()
            Me.cur_assembly = Nothing
            Dim provider As System.CodeDom.Compiler.CodeDomProvider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider(ur_provider) 'New Microsoft.VisualBasic.VBCodeProvider 
            Dim objCOMPILER_RESULT = provider.CompileAssemblyFromSource(ur_compiler_parm, ur_code) ' Strapd().d("Namespace Mx").dLine("Public Class Class1").dLine("Public Shared Function RetVal() As String").dLine("RetVal=""Hi""").dLine("End Function").dLine("End Class").dLine("End Namespace"))
            If objCOMPILER_RESULT.Errors.Count = 0 Then
                Me.cur_assembly = objCOMPILER_RESULT.CompiledAssembly

            Else
                stpERR_MSG.dLine("Compile Errors")
                stpERR_MSG.dLine()
                For Each errItem As System.CodeDom.Compiler.CompilerError In objCOMPILER_RESULT.Errors
                    stpERR_MSG.dLine(errItem.ErrorText & " [" & errItem.Line + 5 & "]")
                    stpERR_MSG.dLine()
                    stpERR_MSG.dLine()
                Next errItem

                stpERR_MSG.dLine(ur_code)
            End If 'objCOMPILER_RESULT

            Compile = stpERR_MSG.ToString
        End Function 'Comiple

        Public Function Run(ur_type_name As String, ur_method_name As String) As String
            Dim stpERR_MSG = Strapd()
            Dim t As System.Type = Me.cur_assembly.CreateInstance(ur_type_name).GetType()
            'Dim objRESULT = t.InvokeMember(ur_method_name, System.Reflection.BindingFlags.InvokeMethod, Nothing, Me.cur_assembly, {})
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing
            For Each m As System.Reflection.MethodInfo In t.GetMethods
                If m.Name = ur_method_name Then
                    objMETHOD_MAIN = m
                    Exit For
                End If
            Next m

            If objMETHOD_MAIN IsNot Nothing Then
                Dim objRESULT = objMETHOD_MAIN.Invoke(Nothing, Nothing)
                If objRESULT IsNot Nothing Then
                    stpERR_MSG.dLine(objRESULT.ToString)
                End If 'objRESULT
            End If 'objMETHOD_MAIN

            Run = stpERR_MSG.ToString
        End Function 'Run
    End Class 'CompileRunner
End Namespace 'Mx

VBNetCode\Send Keys

8th January 2021 at 10:50am
AssignVariable VBCode

Send one alt-tab

System.Windows.Forms.SendKeys.Send("%{TAB}")

Hold down Alt, press alt-tab twice, and release Alt

System.Windows.Forms.SendKeys.Send("%({TAB}{TAB})")

The Windows key is not so easy to emulate. - Auto-It or Auto-Hotkey can do more complicated patterns - VB.Net can use PInvoke to have more capabilities

VBNetCode\Text file to JSON Lines

8th January 2021 at 10:50am
Extract TWCard VBCode

This outputs a file that can be dragged into TiddlyWiki.

<$list variable=cur_char filter="[[UrPK]get[text]splitregexp[\n]join[]split[]each:value[]!match[ ]sort[]]">
<<cur_char>>:
<$list variable=disp_name filter="[[Unicode Char Names]getindex<cur_char>else[missing]]">
<<disp_name>>
</$list><!--disp_name-->
<br>
</$list><!--cur_char-->

[[Unicode Char Names]]
Dim strFILE_PATH = "UnicodeData.txt"
Dim strOUT_PATH = strFILE_PATH & ".json"
Using stmOUT_FILE = New System.IO.StreamWriter(strOUT_PATH)
	Dim qs = """"
	Dim strESC_DQT = "\" & qs
	stmOUT_FILE.Write("[{""created"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & ",""modified"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & "," &
		qs & "title" & qs & ":" & qs & "Unicode Char Names" & qs & ",""type"":""application/json"",""text"":""{")
	Using stmDATA = New System.IO.StreamReader(strFILE_PATH)
		Dim LINCTR = 0
		While stmDATA.EndOfStream = False
			Dim strLINE = stmDATA.ReadLine()
			Dim intFOUND_SPRTR = InStr(strLINE, ";")
			
			Dim strHEX = Mid(strLINE, 1, intFOUND_SPRTR - 1)
			Dim intCHAR = Cint("&H" & strHEX)
			Dim strCHAR = UCase(strHEX)
			Dim strPREFIX = Left(strCHAR, 2)
			If Len(strCHAR) <> 4 Then
				strPREFIX = ""
			End If
			
			If intCHAR < 32 Then
			  strCHAR = ""
			ElseIf intCHAR > 65534 OrElse
			  strPREFIX = "D8" OrElse
			  strPREFIX = "D9" OrElse
			  strPREFIX = "DA" OrElse
			  strPREFIX = "DB" OrElse
			  strPREFIX = "DC" OrElse
			  strPREFIX = "DD" OrElse
			  strPREFIX = "DE" OrElse
			  strPREFIX = "DF" Then
				strCHAR = "\u" & strHEX
			Else
				strCHAR = CHRW(intCHAR)
				If strCHAR = "\" Then
					strCHAR = "\\\\"
				ElseIf strCHAR = """" Then
					strCHAR = "\\\" & """"
				End If
			End If

			If strCHAR <> "" Then
				LINCTR += 1
				If LINCTR > 1 Then
					stmOUT_FILE.Write(",")
				End If
				stmOUT_FILE.Write("\n    " & strESC_DQT & strCHAR & strESC_DQT & ":" & " " & strESC_DQT & strLINE.Replace("\", "\\").Replace(Chr(10), "\n").Replace(qs, strESC_DQT).Replace("<", "&lt;") & strESC_DQT)
			End If
		End While 'stmDATA
	End Using 'stmDATA
	
	stmOUT_FILE.Write("\n}" & qs & "}]")
End Using 'stmOUT_FILE

VBNetCode\To Hex

8th January 2021 at 10:50am
Extract Numbers VBCode

Change string with numbers (0 to 9) and/or letters (a-f) into decimal number

[q/a page]
- https://stackoverflow.com/questions/642417/how-do-you-convert-hex-to-decimal-using-vb-net

[sample code]

Dim strTEXT = "FF"
Dim strHEX_CODE = "&H" & strTEXT
Dim intNUMBER = CInt(strHEX_CODE)
MsgBox(intNUMBER) -> 255

VBNetCode\Unicode Code Point

19th January 2021 at 2:54am

Microsoft DotNet Char ConvertToUTF32

->

  • Note: The index can be any character in the string
retval = char.ConvertToUtf32(s:="A", index:=0).Tostring

Result:

65

VBNetCode\UserBowl example

8th January 2021 at 10:50am
CodeLibrary Extract VBCode
    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As zapp_folder = TRow(Of enmUN).glbl.Trbase(Of zapp_folder).NewBitBase() : Public Class zapp_folder : Inherits enmUN : End Class
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared background_color As zbackground_color = TRow(Of enmUN).glbl.Trbase(Of zbackground_color).NewBitBase() : Public Class zbackground_color : Inherits enmUN : End Class
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_project_code As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared compiler_exe As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared form_title As zform_title = TRow(Of enmUN).glbl.Trbase(Of zform_title).NewBitBase() : Public Class zform_title : Inherits enmUN : End Class
        Public Shared path As zpath = TRow(Of enmUN).glbl.Trbase(Of zpath).NewBitBase() : Public Class zpath : Inherits enmUN : End Class
        Public Shared script_path As zscript_path = TRow(Of enmUN).glbl.Trbase(Of zscript_path).NewBitBase() : Public Class zscript_path : Inherits enmUN : End Class
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared window_status As zwindow_status = TRow(Of enmUN).glbl.Trbase(Of zwindow_status).NewBitBase() : Public Class zwindow_status : Inherits enmUN : End Class
    End Class

    Public Class enmUR_Color
        Inherits bitBASE
        Public Shared Clear As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Green As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Red As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
    End Class

    Public Class enmUR_Status
        Inherits bitBASE
        Public Shared Show As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
        Public Shared Close As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'db.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit(Have.WindowsMsgBox, Have.WindowsCboard)
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)
            Private enrBackground_Color As System.Drawing.Color
            Private enrUR_Color As enmUR_Color

            Public ReadOnly Property Background_Color_of_Form As System.Drawing.Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color_of_Form = Me.enrBackground_Color
                End Get
            End Property 'Background_Color_of_Form

            Public Property Background_Color As enmUR_Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color = Me.enrUR_Color
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As enmUR_Color)
                    Dim intCOLOR = System.Drawing.Color.Transparent
                    If value Is enmUR_Color.Red Then
                        intCOLOR = System.Drawing.Color.Red

                    ElseIf value Is enmUR_Color.Green Then
                        intCOLOR = System.Drawing.Color.Green
                    End If

                    Me.enrBackground_Color = intCOLOR
                    Me.enrUR_Color = value
                    Me.v(enmUB.contents) = value.name
                End Set
            End Property 'Contents

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_bowlname_is(ur_cmp As enmUN) As Boolean
                v_bowlname_is = AreEqual(Me.v(enmUB.bowl_name), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_cmp As enmUR_Color) As Boolean
                v_is = AreEqual(Me.Contents, ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit(ur_windowsmsgbox_env As Have.glblWindowsMsgBox, ur_windowscboard_env As Have.glblWindowsCboard)
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = ur_windowsmsgbox_env.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        ur_windowscboard_env.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Dim strASSEMBLY_EXE = mt
                Try
                    strASSEMBLY_EXE = My.Application.Info.Title
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_FOLDER = FileNamed()
                Try
                    flnASSEMBLY_FOLDER.wAssemblyDir(My.Application.Info)
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_PATH = flnASSEMBLY_FOLDER.gCopy.d(strASSEMBLY_EXE)
                Me.SelKey(enmUN.app_name).Contents = flnASSEMBLY_PATH.FileGroup
                Me.SelKey(enmUN.app_path).Contents = flnASSEMBLY_PATH
                Me.SelKey(enmUN.app_folder).Contents = flnASSEMBLY_FOLDER

                'enmUN.compiler_exe, enmUN.path take the first non-prefixed parameters; they are just file paths but without /parameter_name=
                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText, enmUN.compiler_exe, enmUN.path)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function 'InsFrom_Application

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCboard(ur_hdr As Boolean) As Integer
                ToCboard = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN

VBNetCode\Version

21st February 2021 at 5:26pm

WestWindCom Net Core Runtime

->

SO.com RunTime Net 4.5

->

Function version_info() As String
version_info = "flag CLR 4.5 Features = " & If(Type.GetType(typeName:="System.Reflection.ReflectionContext", throwOnError:=False) Is Nothing, "", "True") & vbCrLf
version_info &= "flag CLR 4.51 Features = " & If(Type.GetType(typeName:="System.Runtime.GCLargeObjectHeapCompactionMode", throwOnError:=False) Is Nothing, "", "True") & vbCrLf
version_info &= "CLR Version = " & System.Environment.Version.ToString & vbCrLf
version_info &= "CLR Local Path = " & System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() & vbCrLf
version_info &= "Operating System = " & CType(System.Attribute.GetCustomAttribute(System.Reflection.Assembly.GetEntryAssembly(), GetType(System.Runtime.Versioning.TargetFrameworkAttribute)), System.Runtime.Versioning.TargetFrameworkAttribute).FrameworkName & " on " & System.Runtime.InteropServices.RuntimeInformation.OSDescription
End Function

VBNetProject

2nd January 2021 at 2:19am
DOC

VBNetProject\~Clear Local

8th January 2021 at 10:50am
CodeLibrary VBCode WindowsCLI
rd /s /q bin
rd /s /q obj
pause

VBNetProject\~Rebiuld Local

8th January 2021 at 10:48am
CodeLibrary Extract VBCode
for %%f in (*.sln) do (
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
	
    for /D %%m in ("C:\Program Files (x86)\MSBuild\*\Bin\MSBuild.exe") do (
        "%%~m" /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
   )
:compile_complete
pause
del ..\Dep\*.exe
move bin\Release\*.exe ..\Dep
rd /s /q bin
rd /s /q obj
pause

VBNetProject\dbUserInputMock

8th January 2021 at 10:47am
CodeLibrary VBCode

Automatically convert the form to the dbUserInput class

Partial Public Class frmInput_1
    <System.Diagnostics.DebuggerHidden()>
    Public Shared Widening Operator CType(b As frmInput_1) As Mx.dbUserInput
        Return New Mx.dbUserInput(b, b.txtNotice_Message)
    End Operator
End Class 'frmInput_1

Setup the mock classes

  • Create flat classes that have the desired values
Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock
End Namespace 'Mx2
  • In a copy of the Mx.dbUserInput class, rename every System.Windows.Forms reference to Mx2.Mock
Option Strict On
Namespace Mx
    Public Class componentTextBox
        Private objTEXT_BOX As System.Windows.Forms.TextBox

        Public Sub New(ur_textbox As System.Windows.Forms.TextBox)
            objTEXT_BOX = ur_textbox
        End Sub

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objTEXT_BOX IsNot Nothing Then
                    Text = objTEXT_BOX.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objTEXT_BOX IsNot Nothing Then
                    objTEXT_BOX.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'componentTextBox

    Public Class dbUserInput
        Private objINPUT_FORM As System.Windows.Forms.Form
        Public txtNotice_Message As componentTextBox

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_input_form As System.Windows.Forms.Form, ur_notice_message_textbox As System.Windows.Forms.TextBox)
            objINPUT_FORM = ur_input_form
            Me.txtNotice_Message = New componentTextBox(ur_notice_message_textbox)
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Close()
            If objINPUT_FORM IsNot Nothing Then
                objINPUT_FORM.Close()
            End If
        End Sub

        Public Property BackColor As System.Drawing.Color
            <System.Diagnostics.DebuggerHidden()>
            Get
                BackColor = Nothing
                If objINPUT_FORM IsNot Nothing Then
                    BackColor = objINPUT_FORM.BackColor
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As System.Drawing.Color)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.BackColor = value
                End If
            End Set
        End Property 'BackColor

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objINPUT_FORM IsNot Nothing Then
                    Text = objINPUT_FORM.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'dbUserInput
End Namespace 'Mx

Create sample data

  • Load the mock dbUserInput with the testing state
Dim mockTextBox = New Mock.TextBox
Dim mockForm = New Mock.Form
Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
Call Mx.UserAction.Run_Script_errhnd(mockUserInput)
  • Compare the mock dbUserInput field changes to the expected result state
Dim strFOUND_RESULT = mockTextBox.Text
If strFOUND_RESULT = strEXPECTED_RESULT Then
	intPASS_COUNT += 1

Else
	intFAIL_COUNT += 1
	stpMOCK_REPORT.dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`").dLine())
End If 'strFOUND_RESULT

VBNetProject\DeveloperSettings

8th January 2021 at 10:47am
CodeLibrary VBCode

VBNetProject\MxBaseEc13

8th January 2021 at 10:47am
CodeLibrary VBCode

MxBase Classes

->

Option Strict On
Namespace Mx '2020m01d03
    Public Module ConstVar
        Public Const mt = ""
        Public Const qs = """"
        Public Const qt = "'"
        Public Const s = " "

        <System.Diagnostics.DebuggerHidden()>
        Public Function AreEqual(ur_val As String, ur_cmp As String) As Boolean
            AreEqual = String.Equals(ur_val, ur_cmp, System.StringComparison.CurrentCultureIgnoreCase)
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b0(ur_val As Integer) As Integer
            b0 = ur_val - 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b1(ur_val As Integer) As Integer
            b1 = ur_val + 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function ContainingText(ur_large_text As String, ur_small_text As String) As Boolean
            ContainingText = InStr(ur_large_text, ur_small_text, CompareMethod.Text) > 0
        End Function 'ContainingText
        <System.Diagnostics.DebuggerHidden()>
        Public Function gUTF8_FileEncoding() As System.Text.UTF8Encoding
            gUTF8_FileEncoding = glbl.gUTF8_Encoding
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function EndingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            EndingWithText = AreEqual(Right(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'EndingWithText
        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText(ur_value As String) As Boolean
            HasText = Not String.IsNullOrWhiteSpace(ur_value)
        End Function 'HasText
        <System.Diagnostics.DebuggerHidden()>
        Public Function StartingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            StartingWithText = AreEqual(Left(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'StartingWithText

        <System.Diagnostics.DebuggerHidden()>
        Public Function CmdOutput(ur_exec_path As String, Optional ur_exec_param As String = mt) As String
            Dim objPCS As New System.Diagnostics.Process()
            With 1 : Dim prcINFO = objPCS.StartInfo
                prcINFO.FileName = ur_exec_path
                prcINFO.Arguments = ur_exec_param
                prcINFO.UseShellExecute = False
                prcINFO.RedirectStandardOutput = True
                prcINFO.CreateNoWindow = True
            End With 'prcINFO

            objPCS.Start()
            CmdOutput = objPCS.StandardOutput.ReadToEnd()
            objPCS.WaitForExit()
        End Function 'CmdOutput

        <System.Diagnostics.DebuggerHidden()>
        Public Function FileNamed() As MxText.FileName
            FileNamed = New MxText.FileName
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Strapd() As Strap
            Strapd = New Strap
        End Function

        Public Class glbl
            Private Shared objUTF8_ENCODING As System.Text.UTF8Encoding

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If objUTF8_ENCODING Is Nothing Then
                    objUTF8_ENCODING = New System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier:=False, throwOnInvalidBytes:=True)
                End If
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function gUTF8_Encoding() As System.Text.UTF8Encoding
                Call glbl.Init()
                gUTF8_Encoding = glbl.objUTF8_ENCODING
            End Function
        End Class 'glbl
    End Module 'ConstVar

    Public Class ErrListBase
        Dim pstpNOTICE_MSG As Strap

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            pstpNOTICE_MSG = Strapd()
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Function DoContinue() As Boolean
            DoContinue = (Me.Found = False)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            If pstpNOTICE_MSG.Length > 0 Then
                pstpNOTICE_MSG.dLine().dLine()
            End If

            pstpNOTICE_MSG.dLine(ur_exception.Message)
            pstpNOTICE_MSG.dLine(Strapd().d("Error in @r1.@r2").r1(ur_methodbase.DeclaringType.Name).r2(ur_methodbase.Name).dS("(status: @r1)").r1(ur_procedure_status))
        End Sub 'dError_Data

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Stack(ur_exception As System.Exception)
            Dim hr As Integer = System.Runtime.InteropServices.Marshal.GetHRForException(ur_exception)
            pstpNOTICE_MSG.dLine(ur_exception.GetType.ToString & "(0x" & hr.ToString("X8") & "): " & ur_exception.Message & System.Environment.NewLine & ur_exception.StackTrace & System.Environment.NewLine)
            Dim st = New System.Diagnostics.StackTrace(ur_exception, True)
            For Each objFRAME In st.GetFrames
                If objFRAME.GetFileLineNumber() > 0 Then
                    pstpNOTICE_MSG.dLine("Line:" & objFRAME.GetFileLineNumber() & " Filename: " & System.IO.Path.GetFileName(objFRAME.GetFileName) & System.Environment.NewLine)
                End If
            Next objFRAME
        End Sub 'dError_Stack

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function Found() As Boolean
            Found = (pstpNOTICE_MSG.Length > 0)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = pstpNOTICE_MSG
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Throw_Error_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            Call Me.dError_Data(ur_exception, ur_methodbase, ur_procedure_status)
            Throw New LocalException(mt)
        End Sub 'Throw_Error_Data


        Public Class LocalException
            Inherits System.Exception

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String)
                MyBase.New(message)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String, inner As System.Exception)
                MyBase.New(message, inner)
            End Sub
        End Class 'LocalException
    End Class 'ErrListBase

    Public Class iWrap(Of T)
        Public v As T

        Public Sub New(ur_t As T)
            Me.v = ur_t
        End Sub
    End Class 'iWrap

    Public Class ObaCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Obalist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list As Obalist(Of T) = Nothing)
            Call MyBase.New(prv.TotalItems(ur_list))
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObaCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property v() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObaCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function TotalItems(Optional ur_list As Obalist(Of T) = Nothing) As Integer
                TotalItems = 0
                If ur_list IsNot Nothing Then
                    TotalItems = ur_list.Count
                End If
            End Function 'TotalItems
        End Class 'prv
    End Class 'ObaCTR

    Public Class ObjCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Objlist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_list As Objlist(Of T))
            Call MyBase.New(ur_list.Count)
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObjCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property row() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                row = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObjCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function
    End Class 'ObjCTR

    Public Class Obalist(Of T)
        Private vobjLIST() As T

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list() As T = Nothing)
            Me.vobjLIST = ur_list
        End Sub

        Public ReadOnly Property Count() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Count = Me.vobjLIST.Length
            End Get
        End Property

        Public Property Item(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                Item = Me.vobjLIST(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.vobjLIST(ur_index) = ur_val
            End Set
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function kvp() As ObaCTR(Of T)
            kvp = New ObaCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Obalist

    Public Class Objlist(Of T)
        Inherits System.Collections.Generic.List(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As ObjCTR(Of T)
            kvp = New ObjCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Objlist

    Public Class SDPCTR(Of T As {New})
        Inherits RCTR

        Private vsdpLIST As SdPair(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdplist As SdPair(Of T))
            Call MyBase.New(ur_sdplist.Count)
            Me.vsdpLIST = ur_sdplist
        End Sub

        Public Shadows ReadOnly Property Current() As SDPCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDPCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property l() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = Me.vsdpLIST.l_enm(Me.Indexenm)
            End Get
        End Property

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdpLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDPCTR

    Public Class SdPair(Of T As {New})
        Inherits Sdata
        Private vobjT As System.Collections.Generic.Dictionary(Of String, T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            vobjT = New System.Collections.Generic.Dictionary(Of String, T)
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function d(ur_val As String, ur_link As T) As SdPair(Of T)
            d = Me
            Call Me.Add(ur_val)
            Call vobjT.Add(ur_val, ur_link)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDPCTR(Of T)
            kvp = New SDPCTR(Of T)(Me)
        End Function

        Public Property l(ur_key As String) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = vobjT.Item(ur_key)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(ur_key) = ur_val
            End Set
        End Property

        Public Property l_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_b1 = vobjT.Item(Me.v_b1(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_b1(ur_index)) = ur_val
            End Set
        End Property

        Public Property l_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_enm = vobjT.Item(Me.v_enm(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_enm(ur_index)) = ur_val
            End Set
        End Property
    End Class 'SdPair

    Public Class RCTR
        Private pintMAX_NUM As Integer
        Private pintCUR_NUM As Integer

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(ByVal b As RCTR) As Integer
            Return b.Indexb1
        End Operator 'CType

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_max_num As Integer)
            Me.pintMAX_NUM = ur_max_num
        End Sub

        Public Shadows ReadOnly Property Current() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me.pintCUR_NUM
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function GetEnumerator() As RCTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public ReadOnly Property Indexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexb1 = Me.pintCUR_NUM
            End Get
        End Property

        Public ReadOnly Property Indexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexenm = b0(Me.pintCUR_NUM)
            End Get
        End Property

        Public ReadOnly Property LastIndexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexb1 = Me.pintMAX_NUM
            End Get
        End Property

        Public ReadOnly Property LastIndexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexenm = b0(Me.pintMAX_NUM)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function MoveNext() As Boolean
            MoveNext = (Me.pintCUR_NUM < Me.pintMAX_NUM)
            Me.pintCUR_NUM += 1
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Reset() As RCTR
            Reset = Me
            Me.pintCUR_NUM = 0
        End Function
    End Class 'RCTR

    Public Class SDACTR
        Inherits RCTR

        Private psdaLIST As Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdata As Sdata)
            Call MyBase.New(ur_sdata.Count)
            Me.psdaLIST = ur_sdata
        End Sub

        Public Shadows ReadOnly Property Current() As SDACTR
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDACTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.psdaLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDACTR

    Public Class Sdata
        Inherits System.Collections.Generic.List(Of String)

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_val As String) As Sdata
            d = Me
            Call Me.Add(ur_val)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ParamArray ur_val() As String) As Sdata
            dList = Me
            If ur_val IsNot Nothing Then
                For Each strENTRY In ur_val
                    If strENTRY Is Nothing Then
                        strENTRY = mt
                    End If

                    Call Me.Add(strENTRY)
                Next strENTRY
            End If
        End Function 'dList

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As Sdata
            gCopy = New Sdata().dList(Me.ToArray)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDACTR
            kvp = New SDACTR(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Split(ur_text As String, ur_sprtr As Char) As Sdata
            Dim sdaCMP = New Sdata
            Split = sdaCMP
            For Each strTEXT In ur_text.Split(ur_sprtr)
                sdaCMP.Add(strTEXT)
            Next
        End Function 'Split

        Public Property v_b1(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property v_enm(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Sdata

    Public Class Strap
        Private pstbTEXT As System.Text.StringBuilder

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            Me.pstbTEXT = New System.Text.StringBuilder
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(b As Strap) As String
            Return b.ToString
        End Operator

        <System.Diagnostics.DebuggerHidden()>
        Public Function Clear() As Strap
            Clear = Me
            Call Me.pstbTEXT.Clear()
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_text As String) As Strap
            d = Me.dSprtr(mt, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSV_Quoted(ur_index_b1 As Integer, ur_text As String) As Strap
            dCSV_Quoted = Me
            If ur_index_b1 > 1 Then
                Me.d(",")
            End If

            Me.d(qs).d(ur_text.Replace(qs, qs & qs)).d(qs)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ur_sprtr As String, ParamArray ur_text() As String) As Strap
            dList = Me
            If ur_text IsNot Nothing Then
                For Each strENTRY In ur_text
                    Call Me.dSprtr(ur_sprtr, strENTRY)
                Next strENTRY
            End If
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSVList(ParamArray ur_text() As String) As Strap
            dCSVList = Me
            If ur_text IsNot Nothing Then
                For ENTCTR = 0 To UBound(ur_text)
                    Me.dCSV_Quoted(ENTCTR + 1, ur_text(ENTCTR))
                Next ENTCTR
            End If
        End Function 'dCSVList

        <System.Diagnostics.DebuggerHidden()>
        Public Function dLine(Optional ur_text As String = "") As Strap
            dLine = Me.dSprtr(vbCrLf, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dS(ur_text As String) As Strap
            dS = Me.dSprtr(s, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dSprtr(ur_sprtr As String, ur_text As String) As Strap
            dSprtr = Me
            Me.pstbTEXT.Append(ur_sprtr).Append(ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function gCopy(ur_text As String) As Strap
            gCopy = New Strap().d(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText() As Boolean
            HasText = (Me.Length > 0)
        End Function

        Public ReadOnly Property Length As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Length = Me.pstbTEXT.Length
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function r1(ur_text As String) As Strap
            r1 = Me
            Call Me.pstbTEXT.Replace("@r1", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function r2(ur_text As String) As Strap
            r2 = Me
            Call Me.pstbTEXT.Replace("@r2", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function rx(ur_index As Integer, ur_text As String) As Strap
            rx = Me
            Call Me.pstbTEXT.Replace("@r" & ur_index, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = Me.pstbTEXT.ToString
        End Function
    End Class 'Strap

    Public Class bitBASE
        Public name As String
        Public seq As Integer
    End Class

    Public Class TRow(Of T As {New, bitBASE})
        Inherits Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            For Each intVAL In Me.RefColNames
                Me.Add(mt)
            Next
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Index_TableSplit(ur_table As Objlist(Of TRow(Of T)), ur_key As T) As SdPair(Of Objlist(Of TRow(Of T)))
            Dim sdpRET = New SdPair(Of Objlist(Of TRow(Of T)))
            Index_TableSplit = sdpRET
            Dim tblCHUNK As Objlist(Of TRow(Of T)) = Nothing
            For Each rowCHUNK In ur_table
                Dim strINDEX = rowCHUNK.v(ur_key)
                Dim intFOUND = sdpRET.IndexOf(strINDEX)
                If intFOUND < 0 Then
                    tblCHUNK = New Objlist(Of TRow(Of T))
                    sdpRET.d(strINDEX, tblCHUNK)
                Else
                    tblCHUNK = sdpRET.l_enm(intFOUND)
                End If

                tblCHUNK.Add(rowCHUNK)
            Next rowCHUNK

            Call sdpRET.Sort()
        End Function 'Index_TableSplit


        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As TRow(Of T)
            Dim sdaRET = New TRow(Of T)
            gCopy = sdaRET
            For Each kvpENTRY In Me.kvp
                sdaRET.v_enm(kvpENTRY.Indexenm) = kvpENTRY.v
            Next kvpENTRY
        End Function

        Public Function Link_Table(ur_table As Objlist(Of TRow(Of T)), ParamArray ur_key_list() As T) As Objlist(Of TRow(Of T))
            Dim tblRET = New Objlist(Of TRow(Of T))
            Link_Table = tblRET
            For Each rowCHUNK In ur_table
                Dim bolFOUND = True
                For Each intKEY In ur_key_list
                    If AreEqual(rowCHUNK.v(intKEY), Me.v(intKEY)) = False Then
                        bolFOUND = False
                        Exit For
                    End If
                Next intKEY

                If bolFOUND Then
                    tblRET.Add(rowCHUNK)
                End If
            Next rowCHUNK
        End Function 'Link_Table

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function PersistRead(ur_persist_path As String) As Objlist(Of TRow(Of T))
            Dim ttbRET = New Objlist(Of TRow(Of T))
            PersistRead = ttbRET
            If Mx.glbl.gWindowsFS.HasFile(ur_persist_path) Then
                Dim bolFIRST_LINE = True
                Dim lstREF_COL = New Objlist(Of T)
                Using stmIN_FILE = Mx.glbl.gWindowsFS.ReadStream(ur_persist_path)
                    Dim strLINE = mt
                    While stmIN_FILE.EndOfStream = False
                        strLINE &= stmIN_FILE.ReadLine
                        Dim bolBALANCED_QUOTES = True
                        For CHRCTR = 0 To strLINE.Length - 1
                            If strLINE(CHRCTR) = """"c Then
                                bolBALANCED_QUOTES = Not bolBALANCED_QUOTES
                            End If
                        Next CHRCTR

                        If bolBALANCED_QUOTES = False Then
                            strLINE &= vbCrLf

                        Else
                            Dim new_row = New TRow(Of T)
                            If Left(strLINE, 1) = vbLf Then
                                strLINE = Mid(strLINE, 2)
                            End If

                            If bolFIRST_LINE = True Then
                                bolFIRST_LINE = False
                                Dim bolCOL_MATCH = False
                                Dim sdaFIRST_ROW = MxText.CSVSplit(strLINE, vbTab)
                                For Each strENTRY In MxText.CSVSplit(strLINE, vbTab)
                                    Dim enmFOUND_KEY As T = Nothing
                                    For Each enmKEY In new_row.RefColKeys
                                        If AreEqual(enmKEY.name, strENTRY) Then
                                            enmFOUND_KEY = enmKEY
                                            bolCOL_MATCH = True
                                            Exit For
                                        End If
                                    Next enmKEY

                                    lstREF_COL.Add(enmFOUND_KEY)
                                Next strENTRY

                                If bolCOL_MATCH = False Then
                                    Exit While
                                End If

                            ElseIf HasText(strLINE) Then
                                For Each kvpCOL In MxText.CSVSplit(strLINE, vbTab).kvp
                                    Dim enmKEY = lstREF_COL.Item(kvpCOL.Indexenm)
                                    If enmKEY IsNot Nothing Then
                                        new_row.v(enmKEY) = kvpCOL.v
                                    End If
                                Next kvpCOL

                                ttbRET.Add(new_row)
                            End If 'bolFIRST_LINE

                            strLINE = mt
                        End If 'bolBALANCED_QUOTES
                    End While
                End Using 'stmIN_FILE
            End If 'ur_persist_path
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Sub PersistWrite(ur_table As Objlist(Of TRow(Of T)), ur_persist_path As MxText.FileName)
            If Mx.glbl.gWindowsFS.HasDir(ur_persist_path.gParentDir) = False Then
                Mx.glbl.gWindowsFS.CreateDirectory(ur_persist_path.gParentDir)
            End If

            Using stmOUT_FILE = Mx.glbl.gWindowsFS.WriteStream(ur_persist_path)
                For Each kvpROW In ur_table.kvp
                    stmOUT_FILE.Write(kvpROW.row.ToString(kvpROW.Indexb1 = 1, True))
                Next
            End Using 'stmOUT_FILE
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeys() As Objlist(Of T)
            RefColKeys = TRow(Of T).glbl.RefKeys
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeySearch(ur_name As String) As Objlist(Of T)
            RefColKeySearch = TRow(Of T).glbl.RefKeySearch(ur_name)
        End Function 'RefColKeySearch

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColNames() As Sdata
            RefColNames = TRow(Of T).glbl.RefNames
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ToCbrd(ur_hdr As Boolean) As Integer
            ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean, Optional ur_quoted As Boolean = False) As Strap
            Dim stpRET = New Strap
            ToString = stpRET
            If ur_hdr Then : For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : stpRET.d(kvpCOL.v) : Next kvpCOL : stpRET.dLine() : End If
            For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : If ur_quoted Then : stpRET.d(qs).d(Me.v_enm(kvpCOL.Indexenm).Replace(qs, qs & qs)).d(qs) : Else : stpRET.d(Me.v_enm(kvpCOL.Indexenm)) : End If : Next kvpCOL : stpRET.dLine()
        End Function


        Public Property v(ur_cl As T) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.Item(ur_cl.seq)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = ""
                End If

                Me.Item(ur_cl.seq) = ur_val
            End Set
        End Property

        Public Class glbl
            Private Shared sdaTCOL_NAME As Sdata
            Private Shared sdjTCOL_KEY As Objlist(Of T)

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME Is Nothing Then
                    Dim objTEST = GetType(T).GetFields()(0).GetValue(Nothing)
                End If

                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME IsNot Nothing Then
                    sdjTCOL_KEY = New Objlist(Of T)
                    Dim tpeCMP = GetType(T)
                    For Each kvpCOL In sdaTCOL_NAME.kvp
                        For Each objPROP In tpeCMP.GetFields()
                            If tpeCMP.DeclaringType Is tpeCMP Then
                                Dim objBIT = DirectCast(objPROP.GetValue(Nothing), bitBASE)
                                If objBIT.seq = kvpCOL.Indexenm Then
                                    sdjTCOL_KEY.Add(DirectCast(objPROP.GetValue(Nothing), T))
                                    Exit For
                                End If
                            End If 'tpeCMP
                        Next objPROP
                    Next kvpCOL
                End If 'sdaTCOL_NAME
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Function NewProp() As T
                Dim objRET = New T
                NewProp = objRET

                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Function 'NewProp

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub NewProp(ur_prop As T)
                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function NewBitBase() As T
                NewBitBase = glbl.NewProp()
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub NewBitBase(ur_prop As T)
                Call glbl.NewProp(ur_prop)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeys() As Objlist(Of T)
                Call glbl.Init()
                RefKeys = glbl.sdjTCOL_KEY
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeySearch(ur_name As String) As Objlist(Of T)
                Call glbl.Init()
                Dim ttbRET = New Objlist(Of T)
                RefKeySearch = ttbRET
                Dim intFOUND_INDEX = TRow(Of T).glbl.RefNames.IndexOf(ur_name)
                If intFOUND_INDEX >= b0(1) Then
                    ttbRET.Add(TRow(Of T).glbl.RefKeys(intFOUND_INDEX))
                End If
            End Function 'RefKeySearch

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefNames() As Sdata
                Call glbl.Init()
                RefNames = glbl.sdaTCOL_NAME
            End Function

            Public Class Trbase(Of W As {New, T})
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function NewBitBase() As W
                    Dim objRET = New W
                    NewBitBase = objRET
                    Call TRow(Of T).glbl.NewBitBase(objRET)
                End Function
            End Class 'Trbase
        End Class 'glbl
    End Class 'Trow

    Partial Public Class MxText 'Parse
        Public Class enmCMD_RET
            Inherits bitBASE
            Public Shared eq As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared fslash As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs_end As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared txt As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared unk As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared ws As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
        End Class

        Public Class Cmdline_UB(Of T As {New, bitBASE}, W As {New, bitBASE})
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                CommandLine_UBParm = prv.CommandLine_UBParm(ur_ub_key, ur_ub_val, ur_source_text, ur_default_field_list)
            End Function

            Class sCMDLINE
                Inherits Mx.Objlist(Of TRow(Of enmCMD_RET))

                <System.Diagnostics.DebuggerHidden()>
                Public Overloads Function ToString(ur_hdr As Boolean) As String
                    Dim stpRET = Strapd() : For Each kvpREC In Me.kvp : stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr)) : Next kvpREC : ToString = stpRET
                End Function 'ToString
                <System.Diagnostics.DebuggerHidden()>
                Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                End Function
            End Class 'sCMDLINE

            Class sCMD_RET
                Public ttbUB_PARM As Objlist(Of TRow(Of W))
                Public ttbCMD_PARM As sCMDLINE
            End Class

            Partial Private Class prv
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                    Dim objRET = New sCMD_RET
                    CommandLine_UBParm = objRET
                    objRET.ttbUB_PARM = New Objlist(Of TRow(Of W))
                    objRET.ttbCMD_PARM = New sCMDLINE
                    Dim rowCMD_PARM = New TRow(Of enmCMD_RET)
                    objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                    Dim sdaDEFAULT_PARMNAME = New Sdata
                    Dim sdaDEST_PARMS = TRow(Of T).glbl.RefNames
                    For Each intUN In ur_default_field_list
                        sdaDEFAULT_PARMNAME.d(intUN.name)
                    Next

                    Dim stpCOMPILE = Strapd()
                    Dim intPREV_CHUNK = enmCMD_RET.ws
                    Dim intCHUNK_C = enmCMD_RET.ws
                    For CHRCTR = 0 To ur_source_text.Length - 1
                        Dim chrC = ur_source_text(CHRCTR)
                        intCHUNK_C = gChunkType(chrC)
                        Dim intSPAN = 1
                        For SPNCTR = CHRCTR + 1 To ur_source_text.Length - 1
                            Dim chrS = ur_source_text(SPNCTR)
                            Dim intSPAN_C = gChunkType(chrS)
                            If intSPAN_C IsNot intCHUNK_C OrElse
                              intSPAN_C Is enmCMD_RET.qs Then
                                'Combine all chunks except for escaped quotes
                                intSPAN = SPNCTR - CHRCTR
                                Exit For
                            End If

                            If SPNCTR = ur_source_text.Length - 1 Then
                                intSPAN = SPNCTR + 1 - CHRCTR
                                Exit For
                            End If
                        Next SPNCTR

                        Dim strCHUNK = ur_source_text.Substring(CHRCTR, intSPAN)
                        If intPREV_CHUNK Is enmCMD_RET.ws Then
                            'Have ws, skip compiled ws; wait for fslash or default parm
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'skip compiled fslash
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip ws between parameters

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'compile unquoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = enmCMD_RET.txt
                                stpCOMPILE.Clear.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.fslash Then
                            'Have ws-fslash, compile txt parm name; wait for eq
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'qs between parm name and eq is unk
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq Then
                                'skip compile qe
                                rowCMD_PARM.v(enmCMD_RET.fslash) = stpCOMPILE.ToString
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = enmCMD_RET.eq

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'compile txt into parm name
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.eq Then
                            'Have ws-fslash-eq, skip compile; wait for txt
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'flush parameter as "=true"; start new parameter
                                stpCOMPILE.Clear.d("true")
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted parameter value
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'keep ws in eq

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'skip eq between paramater name and value

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'store param name, compile unquoted parameter value
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.txt Then
                            'Have ws-fslash-eq-txt, compile parm val; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                'Keep fslash and qs in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'Keep eq in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs Then
                            'Have ws-fslash-eq-qs, compile parm val; wait for qs_end
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'Keep fslash in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'hold parameter; skip this qs and look for another escaped qs or flush the parameter
                                intPREV_CHUNK = enmCMD_RET.qs_end

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'Keep ws, eq and txt in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs_end Then
                            'Have ws-fslash-eq-qs-qsend, compile parm val without ending quote; wait for qs or ws
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'qs_end then fslash without ws between is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'keep escaped qs
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'qs_end then ws or txt is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.unk Then
                            'Have unk, skip compile; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip parameter; start new parameter
                                rowCMD_PARM.v(enmCMD_RET.txt) = stpCOMPILE.ToString
                                rowCMD_PARM = New TRow(Of enmCMD_RET)
                                objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If
                        End If

                        CHRCTR += intSPAN - 1

                        If CHRCTR = ur_source_text.Length - 1 Then
                            'On last entry
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse intCHUNK_C Is enmCMD_RET.eq Then
                                'flush default parameter value
                                stpCOMPILE.Clear.d("true")
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs OrElse intCHUNK_C Is enmCMD_RET.txt Then
                                'flush parameter
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip trailing ws
                            End If
                        End If
                    Next CHRCTR
                End Function 'CommandLine_Chunk

                Private Class Flush_Ret
                    Public rowCMD_PARM As TRow(Of enmCMD_RET)
                    Public intPREV_CHUNK As enmCMD_RET
                End Class

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function Flush_Parameter(ur_ub_key As W, ur_ub_val As W, ur_cmdparm_row As TRow(Of enmCMD_RET), ur_parm_val As Strap, ur_new_prevchunk As enmCMD_RET, ur_refname_list As Sdata, ur_objret_arl As sCMD_RET) As Flush_Ret
                    Dim objRET = New Flush_Ret
                    Flush_Parameter = objRET
                    objRET.rowCMD_PARM = New TRow(Of enmCMD_RET)
                    ur_objret_arl.ttbCMD_PARM.Add(objRET.rowCMD_PARM)
                    objRET.intPREV_CHUNK = ur_new_prevchunk
                    'flush parameter
                    ur_cmdparm_row.v(enmCMD_RET.txt) = ur_parm_val
                    Dim intFOUND = ur_refname_list.IndexOf(ur_cmdparm_row.v(enmCMD_RET.fslash).ToLower)
                    If intFOUND >= 0 Then
                        With 1 : Dim sdaROW = New TRow(Of W)
                            sdaROW.v(ur_ub_key) = ur_refname_list.v_enm(intFOUND)
                            sdaROW.v(ur_ub_val) = ur_cmdparm_row.v(enmCMD_RET.txt)
                            ur_objret_arl.ttbUB_PARM.Add(sdaROW)
                        End With

                        'Skip parameter if not found
                    End If

                    ur_parm_val.Clear()
                End Function

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function gChunkType(ur_char As Char) As enmCMD_RET
                    If ur_char = vbCr OrElse
                  ur_char = vbLf OrElse
                  ur_char = " "c OrElse
                  ur_char = vbTab Then
                        gChunkType = enmCMD_RET.ws

                    ElseIf ur_char = "="c OrElse
                  ur_char = ":"c Then
                        gChunkType = enmCMD_RET.eq

                    ElseIf ur_char = "/"c Then
                        gChunkType = enmCMD_RET.fslash

                    ElseIf ur_char = """"c Then
                        gChunkType = enmCMD_RET.qs

                    Else
                        gChunkType = enmCMD_RET.txt
                    End If
                End Function 'gChunkType
            End Class 'prv
        End Class
    End Class 'MxText-Parse

    Partial Public Class MxText
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function CSVSplit(ByVal ur_line As String, Optional ur_separator As String = ",") As Sdata
            Dim sdaCMP = New Sdata
            CSVSplit = sdaCMP
            Dim objARRAY = ur_line.ToCharArray
            Dim objSPRTR = Mid(ur_separator, 1, 1).ToCharArray()(0)
            Dim objESCAPE_QUOTE = """"c

            Const cstSTART = 0
            Const cstESC = 1
            Const cstQS = 2
            Dim intPARSE_STATE = cstSTART
            Dim intLEN = Len(ur_line) - 1
            Dim stpFIELD As New Strap
            For intIX = 0 To intLEN
                Dim objCHR = objARRAY(intIX)
                Select Case intPARSE_STATE
                    Case cstESC
                        stpFIELD.d(objCHR)
                        intPARSE_STATE = cstQS

                    Case cstQS
                        If objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstSTART
                            Dim intNEXT_IX = intIX + 1
                            If intNEXT_IX < intLEN Then
                                If objARRAY(intNEXT_IX) = objESCAPE_QUOTE Then
                                    intPARSE_STATE = cstESC
                                End If 'intNEXT_IX
                            End If 'intNEXT_IX

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR

                    Case cstSTART
                        If objCHR = objSPRTR Then
                            sdaCMP.d(stpFIELD.ToString)
                            Call stpFIELD.Clear()

                        ElseIf objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstQS

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR
                End Select 'intPARSE_STATE
            Next intIX

            sdaCMP.d(stpFIELD)
        End Function 'CSVSplit
    End Class 'MxText-Csv

    Public Class MxText
        Public Class FileName
            Public FilePath As String
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.FilePath = mt
            End Sub 'New
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(ur_path As String)
                Me.FilePath = ur_path
            End Sub 'New

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As FileName) As String
                Return b.FilePath
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As String) As FileName
                Return New FileName(b)
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shadows Function ToString() As String
                ToString = Me.FilePath
            End Function 'ToString

            <System.Diagnostics.DebuggerHidden()>
            Public Function dAppendEXT(ur_ext As String) As FileName
                dAppendEXT = Me
                If ur_ext.StartsWith(".") = False Then
                    ur_ext = "." & ur_ext
                End If

                Me.FilePath &= ur_ext
            End Function 'dAppendEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function d(ur_file_name As String) As FileName
                d = Me
                If HasText(Me.FilePath) Then
                    Me.FilePath = System.IO.Path.Combine(Me.FilePath, ur_file_name)

                Else 'Me
                    Me.FilePath = ur_file_name
                End If 'Me
            End Function 'd

            <System.Diagnostics.DebuggerHidden()>
            Public Function dNowTextYMDHMS(ur_file_name As String, Optional ur_separator As String = "_") As FileName
                dNowTextYMDHMS = Me
                Me.d(ur_file_name & ur_separator & Now().ToString("yyyy\mMM\dddthh\mmm\sss").Replace("P12", "N12").Replace("A12", "A00").ToLower)
            End Function 'dNowTextYMDHMS

            Public Property Ext() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Ext = System.IO.Path.GetExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wEXT(value)
                End Set
            End Property 'Ext

            Public ReadOnly Property ExtAll() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ExtAll = Strapd().dList(mt, Me.ExtList.ToArray)
                End Get
            End Property 'ExtAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function ExtList() As Sdata
                Dim sdaDESC = Sdata.Split(Me.FilePath, "."c)
                ExtList = sdaDESC
                sdaDESC.RemoveAt(0)
                For Each ROWCTR In sdaDESC.kvp
                    sdaDESC.v_b1(ROWCTR) = "." & sdaDESC.v_b1(ROWCTR)
                Next ROWCTR
            End Function 'ExtList

            Public Property FileGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileGroup = System.IO.Path.GetFileNameWithoutExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.Ext
                End Set
            End Property 'FileGroup

            Public Property FileBaseGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileBaseGroup = mt
                    For Each strENTRY In Sdata.Split(Me.Name, "."c)
                        FileBaseGroup = strENTRY
                        Exit For
                    Next
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.ExtAll
                End Set
            End Property 'FileBaseGroup

            <System.Diagnostics.DebuggerHidden()>
            Public Function gCopy() As FileName
                gCopy = New FileName(Me)
            End Function 'gCopy

            <System.Diagnostics.DebuggerHidden()>
            Public Function gFullPath() As FileName
                gFullPath = New FileName(glbl.gWindowsFS.GetFullPath(Me.FilePath))
            End Function 'gFullPath

            <System.Diagnostics.DebuggerHidden()>
            Public Function gParentDir() As FileName
                gParentDir = New FileName(Me.ParentDir)
            End Function 'gParentDir

            Public Property Name() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Name = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If

                    If HasText(strPATH) Then
                        Name = System.IO.Path.GetFileName(strPATH)
                    End If
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wParentDir.d(value)
                End Set
            End Property 'Name

            Public Property ParentDir() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ParentDir = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If 'strPATH

                    If HasText(strPATH) Then
                        ParentDir = System.IO.Path.GetDirectoryName(strPATH)
                    End If 'strPATH
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Dim strFILE_NAME = Me.Name
                    If HasText(value) Then
                        Me.FilePath = System.IO.Path.Combine(value, strFILE_NAME)

                    Else 'value
                        Me.FilePath = strFILE_NAME
                    End If 'value
                End Set
            End Property 'ParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function ParentList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH = Me.PathList
                ParentList = sdaPATH
                sdaPATH.RemoveAt(b0(sdaPATH.Count))
            End Function 'ParentList

            <System.Diagnostics.DebuggerHidden()>
            Public Function PathList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH As New System.Collections.Generic.List(Of FileName)
                PathList = sdaPATH

                Dim sdaDESC = New Objlist(Of FileName)
                sdaDESC.Add(Me.gCopy)
                Dim objREDUCE = Me.gCopy
                Call objREDUCE.wParentDir()
                While HasText(objREDUCE.FilePath)
                    sdaDESC.Add(objREDUCE.gCopy)
                    Call objREDUCE.wParentDir()
                End While 'objREDUCE

                For Each objFILE In sdaDESC
                    sdaPATH.Add(objFILE)
                Next objFILE
            End Function 'PathList

            <System.Diagnostics.DebuggerHidden()>
            Public Function wAssemblyDir(ur_assembly_info As Microsoft.VisualBasic.ApplicationServices.AssemblyInfo) As FileName
                wAssemblyDir = Me
                Me.FilePath = ur_assembly_info.DirectoryPath.Replace("\bin\Debug", mt)
            End Function 'wAssemblyDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wClear() As FileName
                wClear = Me
                Me.FilePath = mt
            End Function 'wClear

            <System.Diagnostics.DebuggerHidden()>
            Public Function wEXT(ur_ext As String) As FileName
                wEXT = Me
                Dim strFILE_NAME = Me.FileGroup
                If Left(ur_ext, 1) <> "." Then
                    ur_ext = "." & ur_ext
                End If 'ur_ext

                Me.wParentDir.d(strFILE_NAME & ur_ext)
            End Function 'wEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function wParentDir() As FileName
                wParentDir = Me
                Me.FilePath = Me.ParentDir
            End Function 'wParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wTempFileName(ur_fs_proxy As Microsoft.VisualBasic.MyServices.FileSystemProxy) As FileName
                wTempFileName = Me
                Me.FilePath = ur_fs_proxy.GetTempFileName
                Call ur_fs_proxy.DeleteFile(Me.FilePath)
            End Function 'wTempFileName
        End Class 'FileName
    End Class 'MxText-FileName

    Partial Public Class glbl
        Public Class gCboard
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Clear()
                Call My.Computer.Clipboard.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetText() As String
                GetText = My.Computer.Clipboard.GetText
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function SetText(ur_text As String) As Integer
                If HasText(ur_text) Then
                    Call My.Computer.Clipboard.SetText(ur_text)
                    SetText = 1 + ur_text.Length - ur_text.Replace(vbLf, mt).Length
                Else
                    Call My.Computer.Clipboard.Clear()
                    SetText = 0
                End If
            End Function 'SetText
        End Class 'gCboard

        Public Class gDiagnostics
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function IsRunningWindow(ur_title As String) As Boolean
                IsRunningWindow = False
                For Each objCUR_PROC In System.Diagnostics.Process.GetProcesses()
                    If objCUR_PROC.MainWindowHandle.ToInt32 <> 0 AndAlso
                      AreEqual(objCUR_PROC.MainWindowTitle, ur_title) Then
                        IsRunningWindow = True
                        Exit For
                    End If
                Next objCUR_PROC
            End Function 'IsRunningWindow

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Read_CommandLineText(ur_exec_path As String, ur_exec_param As String) As String
                Dim prcCOMMAND_LINE = gDiagnostics.Start_CommandLine_Program(ur_exec_path, ur_exec_param)
                Read_CommandLineText = prcCOMMAND_LINE.StandardOutput.ReadToEnd()
                prcCOMMAND_LINE.WaitForExit()
            End Function 'Read_CommandLineText

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Start_CommandLine_Program(ur_exec_path As String, ur_exec_param As String) As System.Diagnostics.Process
                Dim retPROCESS As New System.Diagnostics.Process()
                Start_CommandLine_Program = retPROCESS
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.UseShellExecute = False
                    prcINFO.RedirectStandardOutput = True
                    prcINFO.RedirectStandardError = True
                    prcINFO.CreateNoWindow = True
                End With 'prcINFO

                retPROCESS.Start()
            End Function 'Start_Procses

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Start_Windows_Program(ur_exec_path As String, ur_exec_param As String)
                Dim retPROCESS As New System.Diagnostics.Process()
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.Verb = "Open"
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
                    prcINFO.UseShellExecute = True
                End With 'prcINFO

                retPROCESS.Start()
            End Sub 'Start_Procses
        End Class 'gDiagnostics

        Public Class gInteraction
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub AppActivate(ur_window_title As String)
                Microsoft.VisualBasic.Interaction.AppActivate(ur_window_title)
            End Sub
        End Class 'gInteraction

        Public Class gEnvironment
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine() As String
                CommandLine = System.Environment.CommandLine
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ExpandEnvironmentVariables(ur_path As String) As String
                ExpandEnvironmentVariables = System.Environment.ExpandEnvironmentVariables(ur_path)
            End Function
        End Class 'gEnvironment

        Public Class gMsgBox
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetResult(ur_message As String, ur_style As MsgBoxStyle, ur_title As String) As MsgBoxResult
                GetResult = MsgBox(ur_message, ur_style, ur_title)
            End Function
        End Class 'gMsgBox

        Public Class gThread
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Sleep(ur_milliseconds As Integer)
                System.Threading.Thread.Sleep(ur_milliseconds)
            End Sub
        End Class 'gThread

        Public Class gWindowsFS
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Copy(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Copy(ur_source_path, ur_dest_path, True)
            End Sub
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub CreateDirectory(ur_folder_path As String)
                System.IO.Directory.CreateDirectory(ur_folder_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Delete(ur_path As String)
                System.IO.File.Delete(ur_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = System.IO.Directory.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetDirectories(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetDirectories = System.IO.Directory.GetDirectories(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFullPath(ur_partial_path As String) As String
                GetFullPath = System.IO.Path.GetFullPath(ur_partial_path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasDir(ur_search_folder As String) As Boolean
                HasDir = System.IO.Directory.Exists(ur_search_folder)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasFile(ur_search_Path As String) As Boolean
                HasFile = System.IO.File.Exists(ur_search_Path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Move(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Move(ur_source_path, ur_dest_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadAllText(ur_file_path As String) As String
                ReadAllText = System.IO.File.ReadAllText(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadStream(ur_file_path As String) As System.IO.StreamReader
                ReadStream = New System.IO.StreamReader(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub WriteAllText(ur_file_path As String, ur_text As String)
                Call System.IO.File.WriteAllText(ur_file_path, ur_text, Mx.gUTF8_FileEncoding())
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function WriteStream(ur_file_path As String) As System.IO.StreamWriter
                WriteStream = New System.IO.StreamWriter(ur_file_path, False, Mx.gUTF8_FileEncoding())
            End Function
        End Class 'gWindowsFS
    End Class 'glbl

    Public Class TablePKEnum(Of E As {New, bitBASE}, P As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of P, T)
        Private PK As E

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_flag_populate_keys As Boolean = True)
            Me.ttb = New System.Collections.Generic.Dictionary(Of P, T)
            Me.PK = TRow(Of E).glbl.RefKeys.tr_b1(1)
            If ur_flag_populate_keys Then
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    Dim new_row = New T
                    new_row.v(Me.PK) = enmENTRY.name
                    Me.ttb.Add(enmENTRY, new_row)
                Next enmENTRY
            End If 'ur_empty_table
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ur_key As P) As Boolean
            ExistsKey = Me.ttb.ContainsKey(ur_key)
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim enmENTRY = prv.Get_PKStr(Me, ur_row)
            If enmENTRY Is Nothing Then
                Throw New System.Exception("Primary Key must exist in the enumeration: " & ur_row.v(Me.PK))

            ElseIf Me.ttb.ContainsKey(enmENTRY) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_row.v(Me.PK))

            Else
                Me.ttb.Add(enmENTRY, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            InsKey = ret
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKEnum(Of E, P, T)
            Dim ttbRET = New TablePKEnum(Of E, P, T)
            PersistRead = ttbRET
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Me.Ins(CType(row, T))
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T()
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ur_key As P) As T
            SelKey = Me.ttb.Item(ur_key)
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                ret = Me.ttb.Item(ur_key)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            UseKey = ret
        End Function 'UseKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        Private Class prv
            Public Shared Sub Assign_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T, ur_key As P)
                ur_row.v(ur_table.PK) = ur_key.name
            End Sub 'Assign_PKStr

            Public Shared Function Get_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T) As P
                Dim ret As P = Nothing
                Dim strPK = ur_row.v(ur_table.PK)
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    If AreEqual(enmENTRY.name, strPK) Then
                        ret = enmENTRY
                        Exit For
                    End If
                Next enmENTRY

                Get_PKStr = ret
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKEnum

    Public Class TablePKStr(Of E As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of String, T)
        Private PK As Objlist(Of E)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_pk_count As Integer)
            Me.ttb = New System.Collections.Generic.Dictionary(Of String, T)
            Me.PK = New Objlist(Of E)
            With 1 : Dim lstKEYS = TRow(Of E).glbl.RefKeys
                Dim intPK_COUNT = ur_pk_count
                If intPK_COUNT > lstKEYS.Count Then
                    intPK_COUNT = lstKEYS.Count
                End If

                For KEYCTR = 1 To ur_pk_count
                    Me.PK.Add(lstKEYS.Item(b0(KEYCTR)))
                Next
            End With 'lstKEYS
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ParamArray ur_key() As String) As Boolean
            ExistsKey = False
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("ExistsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                ExistsKey = Me.ttb.ContainsKey(strPK_KEY_COMBINED)
            End If 'ur_key
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function DelAll() As TablePKStr(Of E, T)
            DelAll = Me
            Call Me.ttb.Clear()
        End Function 'DelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_row)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

            Else
                Me.ttb.Add(strPK_KEY_COMBINED, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("InsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

                Else
                    ret = New T
                    Call prv.Assign_PKStr(Me, ret, ur_key)
                    Me.ttb.Add(strPK_KEY_COMBINED, ret)
                End If 'Me
            End If 'ur_key

            InsKey = ret
        End Function 'InsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKStr(Of E, T)
            PersistRead = Me
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Dim new_row = New T
                For Each enmENTRY In new_row.RefColKeys
                    new_row.v(enmENTRY) = row.v(enmENTRY)
                Next

                Me.Ins(new_row)
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("SelKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    ret = Me.ttb.Item(strPK_KEY_COMBINED)

                Else
                    ret = New T
                End If 'Me
            End If 'ur_key

            SelKey = ret
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelOnKey(ParamArray ur_key() As String) As TablePKStr(Of E, T)
            Dim ret = Me
            For KEYCTR = 1 To Me.PK.Count
                ret = ret.Sel(Me.PK.Item(b0(KEYCTR)), ur_key(b0(KEYCTR)))
            Next

            SelOnKey = ret
        End Function 'SelOnKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                ret = Me.ttb.Item(strPK_KEY_COMBINED)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(strPK_KEY_COMBINED, ret)
            End If

            UseKey = ret
        End Function 'UseKey

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Assign_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T, ur_key() As String)
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                For KEYCTR = 1 To intPK_KEYS
                    ur_row.v(ur_table.PK.Item(b0(KEYCTR))) = ur_key(b0(KEYCTR))
                Next
            End Sub 'Assign_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_key() As String) As String
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To intPK_KEYS
                    If KEYCTR = 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_key(b0(KEYCTR)).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T) As String
                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To ur_table.PK.Count
                    If KEYCTR > 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_row.v_b1(KEYCTR).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKStr


    Partial Public Class Have
        Partial Private Class prv_sample
            Private Class Have
                Private Shared tblUserBowl As sUserBowl

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Sub Connect()
                    If Have.tblUserBowl Is Nothing Then
                        Have.tblUserBowl = New sUserBowl
                    End If 'sdaTCOL_NAME
                End Sub 'Connect

                Public Class enmUB
                    Inherits bitBASE
                    Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                    Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                End Class

                Public Class enmUN
                    Inherits bitBASE
                    Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p1 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p2 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared to_clipboard As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                End Class

                'Public Shared Function UserBowl() As sUserBowl
                '    Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
                '    Call Have.Connect()
                '    UserBowl = Have.tblUserBowl
                '    If bolFIRST_INIT Then
                '        Call Have.tblUserBowl.InsFrom_Application()
                '        Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                '        Call Have.tblUserBowl.Cboard_CmdlineAudit()
                '    End If
                'End Function 'UserBowl

                Public Class rUserBowl
                    Inherits TRow(Of enmUB)

                    <System.Diagnostics.DebuggerHidden()>
                    Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                        vt = Me
                        Me.v(ur_enm) = ur_val
                    End Function

                    'Public Shadows Function Link_Table(ur_child_table As Have.sReport_Detl, ParamArray ur_key_list() As bitRP) As sReport_Detl
                    '    Dim tblRET = New sReport_Detl
                    '    Link_Table = tblRET
                    '    Dim sdpXLAT = New SdPair(Of bitRT)
                    '    Dim stpKEY_BINDINGS = Strapd()
                    '    For Each keyRP In ur_key_list
                    '        stpKEY_BINDINGS.dS(keyRP.name)
                    '        For Each keyRT In ur_child_table.SelFirst.RefColKeys
                    '            If AreEqual(keyRT.name, keyRP.name) Then
                    '                sdpXLAT.d(keyRP.name, keyRT)
                    '            End If
                    '        Next keyRT
                    '    Next keyRP

                    '    If sdpXLAT.Count <> ur_key_list.Length Then
                    '        Throw New System.Exception("Key bindings not found for RT/RP join: " & stpKEY_BINDINGS.ToString)

                    '    Else
                    '        For Each trwJOIN In ur_child_table.SelAll
                    '            Dim bolFOUND = True
                    '            For Each keyRP In ur_key_list
                    '                Dim keyRT = sdpXLAT.l(keyRP.name)
                    '                If AreEqual(trwJOIN.v(keyRT), Me.v(keyRP)) = False Then
                    '                    bolFOUND = False
                    '                    Exit For
                    '                End If
                    '            Next keyRP

                    '            If bolFOUND Then
                    '                tblRET.Ins(trwJOIN)
                    '            End If
                    '        Next trwJOIN
                    '    End If 'sdpXLAT
                    'End Function 'Link_Table
                End Class 'rUserBowl

                Public Class sUserBowl
                    Inherits TablePKEnum(Of enmUB, enmUN, rUserBowl)

                    'Public Sub Cboard_CmdlineAudit()
                    '    If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    '        Dim strAUDIT = Me.ToString(True)
                    '        Dim ins_msg = Mx.Have.MessageBox.Ins(
                    '            New Mx.Have.rMessageBox().
                    '                vt(enmMB.title, Me.SelKey(enmUN.app_name).v(enmUB.contents)).
                    '                vt(enmMB.text, strAUDIT),
                    '            MsgBoxStyle.OkCancel
                    '            )
                    '        If ins_msg.vUserResponse = MsgBoxResult.Ok Then
                    '            Mx.Have.Clipboard.Ins(
                    '                New Mx.Have.rClipboard().
                    '                vt(enmCB.text, strAUDIT)
                    '                )
                    '        End If
                    '    End If
                    'End Sub 'Cboard_CmdlineAudit

                    'Public Function InsFrom_Application() As rUserBowl
                    '    Dim ret = New rUserBowl
                    '    InsFrom_Application = ret
                    '    'Me.InsKey(enmUN.app_name, New MxText.FileName().d(Mx.Class1.SourcePath).FileGroup)
                    '    'Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                    '    'Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                    '    Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                    '    Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                    '    Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                    '    For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    '        Me.Ins(
                    '            New Have.rUserBowl().
                    '            vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                    '            vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                    '            )
                    '    Next
                    'End Function 'InsFrom_Application

                    'Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    '    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                    'End Function
                End Class 'sUserBowl
            End Class 'Have
        End Class 'prv_sample
    End Class 'Have.prv_sample
End Namespace 'Mx

VBNetProject\VBNetScript

8th January 2021 at 10:54am
VBCode WindowsOS

VBNS Project

3rd January 2021 at 12:09am
DOC

VBNS Project\~MockTestReport

8th January 2021 at 10:46am
ErrorHandling Extract VBCode
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
dbUserInputMock.vb
ScriptRun.vb
subs.vb
RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx2

Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock

    Public Class Want
        Public Shared Function CompileCode_Report_errhnd(ur_commandline_text As String) As Mx.Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Mx.Strapd()
            CompileCode_Report_errhnd = stpRET
            stpRET.d("RED").dLine()
            Dim objERR_LIST = New Mx.ErrListBase : Try
                Call Assistant.CompileCode_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'CompileCode_Report_errhnd
    End Class 'Want

    Public Class Assistant
        Public Shared Sub CompileCode_Report(ur_ret As Mx.Strap)
            Dim windowsfs_env = Have.WindowsFS
            Dim userbowl_cart = Have.UserBowl
            Dim appfolder_bowlname = enmUN.app_folder
            Dim mocktest_cart = Have.MockTest
            Dim intRECS_INSERTED = mocktest_cart.Apply(userbowl_cart, appfolder_bowlname, windowsfs_env)
            Dim intRECS_TESTED = mocktest_cart.Apply(windowsfs_env)

            Dim from_messagebox_bowlname = userbowl_cart.Apply(mocktest_cart, ur_ret)
        End Sub 'CompileCode_Report
    End Class 'Assistant

    Partial Public Class Have
        Partial Public Class sMockTest
            Public Function Apply(ur_userbowl_cart As Have.sUserBowl, ur_appfolder_bowlname As enmUN, ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_ADDED = 0
                Dim strSEARCH_TEST_NAME = "MockTest\*.mock_commandline.txt"
                Dim strSEARCH_RESULT_NAME = ".mock_expect.txt"
                Dim flnAPP_FOLDER = Mx.FileNamed.d(ur_userbowl_cart.SelKey(ur_appfolder_bowlname).Contents)
				Dim fltSEARCH_MOCK_COMMANDLINE = flnAPP_FOLDER.gCopy.d(strSEARCH_TEST_NAME)
                For Each strPATH In ur_windowsfs_env.GetFiles(fltSEARCH_MOCK_COMMANDLINE.gParentDir, fltSEARCH_MOCK_COMMANDLINE.Name, System.IO.SearchOption.TopDirectoryOnly)
					
                    Dim flnTEST_FILE_PATH = Mx.FileNamed.d(strPATH)
                    Dim rowMOCK_TEST = Me.InsKey(strPATH)
                    retREC_ADDED += 1
                    Dim flnTEST_CODE_PATH = flnTEST_FILE_PATH.gParentDir.d(Mx.FileNamed().d(flnTEST_FILE_PATH.FileGroup).FileGroup)
                    For Each strTEST_CODE_PATH In ur_windowsfs_env.GetFiles(flnTEST_CODE_PATH.gParentDir, flnTEST_CODE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.test_code_file, strTEST_CODE_PATH)
                        Exit For
                    Next
					
                    Dim flnRESULT_FILE_PATH = flnTEST_CODE_PATH.gCopy.dAppendEXT(strSEARCH_RESULT_NAME)
                    For Each strEXPECTED_RESULT_PATH In ur_windowsfs_env.GetFiles(flnRESULT_FILE_PATH.gParentDir, flnRESULT_FILE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.mock_expect_file, strEXPECTED_RESULT_PATH)
                        Exit For
                    Next
                Next strPATH

                Apply = retREC_ADDED
            End Function 'Apply ur_userbowl_cart

            Public Function Apply(ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_TESTED = 0
                For Each rowMOCK_TEST In Me.SelAll
                    retREC_TESTED += 1
                    If Mx.HasText(rowMOCK_TEST.v(enmMT.test_code_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Test Code File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    ElseIf Mx.HasText(rowMOCK_TEST.v(enmMT.mock_expect_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Mock Expect File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    Else
						Dim strTEST_CODEFILE_PATH = rowMOCK_TEST.v(enmMT.test_code_file)
                        Dim strCOMMANDLINE_PARMS = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_commandline_file))
                        Dim strEXPECTED_RESULT = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_expect_file))

                        Dim mockTextBox = New Mock.TextBox
                        Dim mockForm = New Mock.Form
                        Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
                        Dim stpTEST_COMMANDLINE = Mx.Strapd().d("vbnetscript.exe").dS("/path=").dSprtr(Mx.qs, strTEST_CODEFILE_PATH).d(Mx.qs).dS(strCOMMANDLINE_PARMS)
                        Call Mx.Want.Compile_And_Run_Script_errhnd(mockUserInput, stpTEST_COMMANDLINE)
                        Dim strFOUND_RESULT = mockTextBox.Text
                        If strFOUND_RESULT = strEXPECTED_RESULT Then
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "1")
						
                        Else
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
                            rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`"))
                        End If 'strFOUND_RESULT
                    End If
                Next rowMOCK_TEST

                Apply = retREC_TESTED
            End Function 'Apply ur_windowsfs_env
        End Class 'sMockTest

        Partial Public Class sUserBowl
            Public Function Apply(ur_mocktest_cart As Have.sMockTest, ur_ret As Mx.Strap) As enmUN
                Dim retUN = enmUN.from_messagebox
                Apply = retUN

                Dim intTEST_PASS = 0
                Dim intTEST_FAIL = 0
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "1" Then
                        intTEST_PASS += 1

                    Else
                        intTEST_FAIL += 1
                    End If
                Next rowMOCK_TEST

                If intTEST_PASS = ur_mocktest_cart.SelAll.Count Then
                    ur_ret.Clear().dLine("GREEN").dLine()
                End If

                ur_ret.dLine(intTEST_PASS.ToString).dS("Tests passed")
                ur_ret.dLine(intTEST_FAIL.ToString).dS("Tests failed")
				ur_ret.dLine()
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "0" Then
                        ur_ret.dLine(rowMOCK_TEST.v(enmMT.test_result_text))
						ur_ret.dLine()
                    End If
                Next rowMOCK_TEST
            End Function 'Apply ur_messagebox_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblMockTest As sMockTest
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblMockTest = New sMockTest
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmMT
        Inherits Mx.bitBASE
        Public Shared mock_commandline_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared mock_expect_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_code_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_result_text As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_pass_count As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
    End Class 'enmMT

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function MockTest() As sMockTest
            Call Have.Connect()
            MockTest = Have.tblMockTest
        End Function

        Public Class rMockTest
            Inherits Mx.TRow(Of enmMT)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmMT, ur_val As String) As rMockTest
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rMockTest

        Public Class sMockTest
            Inherits Mx.TablePKStr(Of enmMT, rMockTest)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                MyBase.New(1)
            End Sub
        End Class
    End Class 'enmMT

    Public Class enmUB
        Inherits Mx.bitBASE
        Public Shared bowl_name As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits Mx.bitBASE
        Public Shared app_folder As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits Mx.bitBASE
        Public Shared Ok As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits Mx.TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = Mx.AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If Mx.HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = Mx.MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = Mx.qs & Have.CmdLineText.Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                Me.SelKey(enmUN.cmdline_table).Contents = Mx.qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx2

VBNS Project\~VersionUpd

8th January 2021 at 10:46am
AssignVariable Filter VBCode
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.FileUpdate_Report_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.FileUpdate_Report_errhnd
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub FileUpdate_Report(ur_ret As Strap)
            Dim userbowl_cart = Have.UserBowl
            Dim appname_bowlname = enmUN.app_name
            Dim appfolder_bowlname = enmUN.app_folder
            Dim windows_msgbox_env = Have.WindowsMsgBox
            Dim windows_fs_env = Have.WindowsFS
            Dim tempfile_cart = Have.TempFile
            tempfile_cart.Apply(userbowl_cart.SelKey(appfolder_bowlname), windows_fs_env)
            Dim report_output_bowlname = userbowl_cart.Apply(tempfile_cart)
            Dim from_messagebox_bowlname = userbowl_cart.Apply(
                ur_userbowl_text:=userbowl_cart.SelKey(report_output_bowlname),
                ur_userbowl_appname:=userbowl_cart.SelKey(appname_bowlname),
                ur_messagebox_env:=windows_msgbox_env
                )
        End Sub 'FileUpdate_Report

        Public Shared Function FileUpdate_Report_errhnd() As Strap
            Dim stpRET = Strapd()
            FileUpdate_Report_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call FileUpdate_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'FileUpdate_Report_errhnd
    End Class 'Want

    Partial Public Class Have
        Partial Class sTempFile
            Public Sub Apply(ur_app_folder As Have.rUserBowl, ur_windows_fs_env As Have.glblWindowsFS)
                Dim flnROOT_FOLDER = FileNamed().d(ur_app_folder.v(enmUB.contents))
                Dim flnMY_PROJECT = flnROOT_FOLDER.gCopy.d("My Project")
                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnROOT_FOLDER, "*.vbproj", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.VBProj, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.VBProj).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.VBProj.name).dS("file in folder"))
                End If

                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnMY_PROJECT, "AssemblyInfo.vb", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.AssemblyInfo, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.AssemblyInfo).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.AssemblyInfo.name).dS("file in folder"))
                End If
            End Sub 'Apply(ur_app_folder
        End Class 'sTempFile

        Partial Public Class sUserBowl
            Public Function Apply(ur_userbowl_text As Have.rUserBowl, ur_userbowl_appname As Have.rUserBowl, ur_messagebox_env As Have.glblWindowsMsgBox) As bitBASE
                Dim retUN = enmUN.from_messagebox
                Apply = retUN
                Dim enrUSER_INPUT = ur_messagebox_env.GetResult(
                    ur_message:=ur_userbowl_text.v(enmUB.contents),
                    ur_title:=ur_userbowl_appname.v(enmUB.contents),
                    ur_style:=MsgBoxStyle.OkOnly
                    )

                If enrUSER_INPUT = MsgBoxResult.Ok Then
                    Me.InsKey(retUN, enmUR.Ok)
                End If
            End Function 'Apply ur_messagebox_cart

            Public Function Apply(ur_tempfile_cart As Have.sTempFile) As enmUN
                Dim retUN = enmUN.report_output
                Apply = retUN
                Dim strDATE = Today.ToString("yyyy.MM.dd")
                Dim intCURRENT = 1

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.VBProj.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<ApplicationRevision>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationRevision>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, InStr(strPARSE, "<") - 1)
                                    If System.Int32.TryParse(strPARSE, intCURRENT) Then
                                        intCURRENT += 1
                                    End If

                                ElseIf StartingWithText(strLINE.TrimStart, "<ApplicationVersion>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationVersion>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, 10)
                                    If AreEqual(strPARSE, strDATE) = False Then
                                        intCURRENT = 1
                                    End If 'strPARSE

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationRevision>")
                                    stmSECOND.Write(intCURRENT)
                                    stmSECOND.WriteLine("</ApplicationRevision>")

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationVersion>")
                                    stmSECOND.Write(Strapd().d(strDATE).d(intCURRENT.ToString("00")).d(".%2a"))
                                    stmSECOND.WriteLine("</ApplicationVersion>")

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.AssemblyInfo.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyVersion(") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyVersion").d("(").d(qs).d(Today.ToString("yyyy.MM.dd")).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                ElseIf StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyFileVersion") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyFileVersion").d("(").d(qs).d(strDATE).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                Me.InsKey(retUN, Strapd().d("Files updated:").dS(ur_tempfile_cart.SelAll.Count.ToString))
            End Function 'Apply ur_tempfield_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblTempFile As sTempFile
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblTempFile = New sTempFile
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmTF
        Inherits bitBASE
        Public Shared file_search As enmTF = TRow(Of enmTF).glbl.NewBitBase()
        Public Shared filename As enmTF = TRow(Of enmTF).glbl.NewBitBase()
    End Class

    Public Class enmTN
        Inherits bitBASE
        Public Shared AssemblyInfo As enmTN = TRow(Of enmTN).glbl.NewBitBase()
        Public Shared VBProj As enmTN = TRow(Of enmTN).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function TempFile() As sTempFile
            Call Have.Connect()
            TempFile = Have.tblTempFile
        End Function

        Public Class rTempFile
            Inherits TRow(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmTF, ur_val As String) As rTempFile
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rTempFile

        Public Class sTempFile
            Private ttb As Objlist(Of rTempFile)
            Private PK As Objlist(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rTempFile)
                Me.PK = New Objlist(Of enmTF)
                Me.PK.Add(enmTF.file_search)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Del(ur_col As enmTF, ur_val As String)
                For ROWCTR = Me.ttb.Count To 1 Step -1
                    If AreEqual(Me.ttb.tr_b1(ROWCTR).v(ur_col), ur_val) Then
                        Me.ttb.RemoveAt(b0(ROWCTR))
                    End If
                Next ROWCTR
            End Sub 'Del

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Ins(ur_from As rTempFile)
                Dim ttbSEL = Me
                Dim stpPK_LIST = Strapd()
                For Each keyPK In Me.PK
                    Dim strCUR_KEY = ur_from.v(keyPK)
                    If stpPK_LIST.Length > 0 Then stpPK_LIST.d(", ")
                    stpPK_LIST.d(strCUR_KEY)
                    If HasText(strCUR_KEY) = False Then
                        Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("PK value must have data:").dS(keyPK.name))
                    Else
                        ttbSEL = ttbSEL.Sel(keyPK, ur_from.v(keyPK))
                    End If
                Next keyPK

                If ttbSEL.SelAll.Count > 0 Then
                    Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("must have unique PK values:").dS(stpPK_LIST.ToString))
                Else
                    Me.ttb.Add(ur_from)
                End If
            End Sub 'Ins

            <System.Diagnostics.DebuggerHidden()>
            Public Sub InsKey(ur_key As enmTN, ur_val As String)
                Dim ret = Me.SelKey(ur_key)
                If HasText(ret.v(enmTF.filename)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmTF.filename, ur_val)
                End If
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmTF, ur_value As String) As sTempFile
                Dim retUB = New sTempFile
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rTempFile)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmTN) As rTempFile
                Dim ret As rTempFile = Nothing
                Dim strKEY = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmTF.file_search), strKEY) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rTempFile
                    Me.ttb.Add(
                        ret.
                        vt(enmTF.file_search, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sTempFile
    End Class 'TF

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Private ttb As Objlist(Of rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rUserBowl)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rUserBowl) As rUserBowl
                Ins = ur_from
                Me.ttb.Add(ur_from)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As String) As rUserBowl
                Dim ret = Me.SelKey(ur_key)
                InsKey = ret
                If HasText(ret.v(enmUB.contents)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmUB.contents, ur_val)
                End If
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As enmUR) As rUserBowl
                InsKey = Me.InsKey(ur_key, ur_val.name)
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.InsKey(enmUN.app_name, FileNamed().d(Mx.Class1.SourcePath).FileGroup)
                Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmUB, ur_value As String) As sUserBowl
                Dim retUB = New sUserBowl
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rUserBowl)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmUN) As rUserBowl
                Dim ret As rUserBowl = Nothing
                Dim strUN = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmUB.bowl_name), strUN) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rUserBowl
                    Me.ttb.Add(
                        ret.
                        vt(enmUB.bowl_name, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

VBNS Project\Roman to Decimal

19th January 2021 at 3:49am
Extract Numbers VBCode

Roman to Decimal ZIP

->

  • Asks for a Roman Numeral
  • Returns a decimal number or an error with the invalid sequence and the broken rule
Namespace Mx
	Public Class mb
		Public Shared FirstExec As Object
		Public Shared uinput As Microsoft.VisualBasic.MsgBoxResult

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub ask(ur_text As String)
			Call prv.Connect()
			If mb.uinput <> MsgBoxResult.Cancel Then
				mb.uinput = Microsoft.VisualBasic.MsgBox(ur_text, MsgBoxStyle.OkCancel, "")
			End If
		End Sub 'ask

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Function GetText(ur_question As String) As String
			GetText = Microsoft.VisualBasic.InputBox(ur_question, "")
		End Function

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub reset()
			Call prv.Connect()
			mb.uinput = MsgBoxResult.Ok
		End Sub

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Sub Connect()
				If mb.FirstExec Is Nothing Then
					mb.uinput = MsgBoxResult.Ok
					mb.FirstExec = "done"
				End If
			End Sub 'Connect
		End Class 'prv
	End Class 'mb

	Public Class UserAction
		Public Shared Function Roman_Numeral_Conversion_Report() As String
			mb.reset()
			Dim strRET_MSG = ""
			Dim strNUMERAL = mb.GetText("Enter a Roman numeral")
			Dim strDECIMAL = Assistant.Roman_Numeral_Conversion_Result(strNUMERAL)
			strRET_MSG = strNUMERAL & " rom. = " & strDECIMAL & " dec."
			Roman_Numeral_Conversion_Report = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Report
	End Class 'UserAction

	Public Class Assistant
		Public Shared Function Roman_Numeral_Conversion_Result(ur_numeral As String) As String
			Dim strRET_MSG = ""
			Dim rmnNUMERAL = New Mx.glblRomanNumeral(ur_numeral)
			strRET_MSG = rmnNUMERAL.Validation_Message
			If strRET_MSG = "" Then
				strRET_MSG = rmnNUMERAL.ToInteger.ToString
			End If

			Roman_Numeral_Conversion_Result = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Result
	End Class 'Assistant

	Public Class glblRomanNumeral
		Private strpNumeral As String

		Private Enum enmLH
			low_or_high_number
			high_number
			low_number
		End Enum

		Private siaSymbol_Size As Mx.sia

		<System.Diagnostics.DebuggerHidden()>
		Public Sub New(ur_numeral As String)
			Me.strpNumeral = ur_numeral.Trim.ToUpper
			Me.siaSymbol_Size = prv.glbl_Symbol_Sizes()
		End Sub

		Public ReadOnly Property Numeral As String
			<System.Diagnostics.DebuggerHidden()>
			Get
				Numeral = Me.strpNumeral
			End Get
		End Property 'Numeral

		Public Function IsValid() As Boolean
			IsValid = (Me.Validation_Message = "")
		End Function

		Public Function Validation_Message() As String
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_Valid

			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, "", symbol_size_table)

			Validation_Message = clrRET_STATE.strNOTICE_MSG
		End Function 'Validation_Message

		Public Function ToInteger() As Integer
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_State
			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				Dim clPREV_STATE = clrRET_STATE
				clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, "", symbol_size_table)

			ToInteger = clrRET_STATE.intRET_NUM
		End Function 'ToInteger

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function glbl_Symbol_Sizes() As Mx.sia
				Dim retSIA = New Mx.sia
				glbl_Symbol_Sizes = retSIA
				retSIA.Add("I", 1)
				retSIA.Add("V", 5)
				retSIA.Add("X", 10)
				retSIA.Add("L", 50)
				retSIA.Add("C", 100)
				retSIA.Add("D", 500)
				retSIA.Add("M", 1000)

				glbl_Symbol_Sizes = retSIA
			End Function 'glbl_Symbol_Sizes

			Public Class Loop_State
				Public enrSTATE As enmLH
				Public strLOW_OR_HIGH_TEMP As String
				Public intRET_NUM As Integer

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Me.enrSTATE = enmLH.high_number
					Me.strLOW_OR_HIGH_TEMP = ""
					Me.intRET_NUM = 0
				End Sub 'New
			End Class 'Loop_State

			Public Class Loop_Valid
				Public strVAL_FOUR As String
				Public strVAL_THREE As String
				Public strVAL_TWO As String
				Public strVAL_ONE As String
				Public intVAL_FOUR As Integer
				Public intVAL_THREE As Integer
				Public intVAL_TWO As Integer
				Public intVAL_ONE As Integer
				Public strNOTICE_MSG As String

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Call prvLoop_Valid.Reset_Symobls(Me)
					Me.strNOTICE_MSG = ""
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia)
					Me.strVAL_FOUR = ur_state.strVAL_THREE
					Me.intVAL_FOUR = ur_state.intVAL_THREE
					Me.strVAL_THREE = ur_state.strVAL_TWO
					Me.intVAL_THREE = ur_state.intVAL_TWO
					Me.strVAL_TWO = ur_state.strVAL_ONE
					Me.intVAL_TWO = ur_state.intVAL_ONE
					Me.strVAL_ONE = ur_new_symbol
					Me.intVAL_ONE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
					Me.strNOTICE_MSG = ur_state.strNOTICE_MSG
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub Assign_NoticeMsg(ur_message As String)
					If strNOTICE_MSG <> "" Then
						strNOTICE_MSG &= vbCrLf & vbCrLf
					End If

					strNOTICE_MSG &= ur_message
					Call prvLoop_Valid.Reset_Symobls(Me)
				End Sub 'Assign_NoticeMsg

				Private Class prvLoop_Valid
					Public Shared Sub Reset_Symobls(ur_state As prv.Loop_Valid)
						ur_state.strVAL_FOUR = ""
						ur_state.intVAL_FOUR = 0
						ur_state.strVAL_THREE = ""
						ur_state.intVAL_THREE = 0
						ur_state.strVAL_TWO = ""
						ur_state.intVAL_TWO = 0
						ur_state.strVAL_ONE = ""
						ur_state.intVAL_ONE = 0
					End Sub 'Reset_Symobls
				End Class 'prv
			End Class 'Loop_Valid

			Public Shared Function Loop_Return_Valid(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_Valid
				Dim retSTATE = New prv.Loop_Valid(ur_state, ur_new_symbol, ur_symbol_size)
				Loop_Return_Valid = retSTATE
				If retSTATE.strVAL_ONE <> "" Then
					If retSTATE.intVAL_ONE = 0 Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							If strLIST <> "" Then
								strLIST &= ", "
							End If

							strLIST &= strENTRY
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used in Roman numerals.")

					ElseIf retSTATE.strVAL_FOUR = retSTATE.strVAL_THREE AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_TWO AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_ONE Then
						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_FOUR & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & ur_new_symbol & "] is not valid: A single symbol may not be repeated more than three times.")

					ElseIf retSTATE.strVAL_TWO = retSTATE.strVAL_ONE AndAlso
					  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
							If Left(strENTRY_VAL, 1) = "1" Then
								If strLIST <> "" Then
									strLIST &= ", "
								End If

								strLIST &= strENTRY
							End If
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be repeated.")

					ElseIf retSTATE.strVAL_TWO <> "" Then
						If retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
							Dim strLIST = ""
							For Each strENTRY In ur_symbol_size.Keys
								Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
								If Left(strENTRY_VAL, 1) = "1" Then
									If strLIST <> "" Then
										strLIST &= ", "
									End If

									strLIST &= strENTRY
								End If
							Next strENTRY

							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used as the lower symbol followed by a higher symbol.")

						ElseIf retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  retSTATE.intVAL_ONE <> retSTATE.intVAL_TWO * 10 Then
							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: The lower symbol must be ten times less value than the following higher symbol.")

						ElseIf retSTATE.strVAL_THREE <> "" Then
							If retSTATE.intVAL_TWO > retSTATE.intVAL_ONE AndAlso
							  retSTATE.intVAL_ONE >= retSTATE.intVAL_THREE Then
								retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: A lower symbol followed by higher symbol must be followed by lower symbol than the first of the series.")
							End If
						End If 'strVAL_THREE
					End If 'strVAL_TWO
				End If 'strVAL_ONE
			End Function 'Loop_Return_Valid

			Public Shared Function Loop_Return_State(ur_state As prv.Loop_State, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_State
				Dim retSTATE = New prv.Loop_State
				Loop_Return_State = retSTATE

				Dim intNEW_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
				Dim intLOW_OR_HIGH_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_state.strLOW_OR_HIGH_TEMP)
				If ur_state.strLOW_OR_HIGH_TEMP = "" Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM
					retSTATE.enrSTATE = enmLH.low_or_high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol

				ElseIf intNEW_VALUE > intLOW_OR_HIGH_VALUE Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intNEW_VALUE - intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ""

				Else
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.low_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol
				End If
			End Function 'Loop_Return_State

			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function Numeral_To_Int(ur_symbol_size As Mx.sia, ur_numeral As String) As Integer
				Numeral_To_Int = 0
				If ur_symbol_size.ContainsKey(ur_numeral) Then
					Numeral_To_Int = ur_symbol_size.Item(ur_numeral)
				End If
			End Function 'Numeral_To_Int
		End Class 'prv
	End Class 'glblRomanNumeral

	Public Class sia
		Inherits System.Collections.Generic.Dictionary(Of String, Integer)
	End Class
End Namespace 'Mx

VBNS Project\Wiki_Move_HTM

8th January 2021 at 10:46am
Filter TWCard VBCode

Wiki Move HTM

->

@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
End Function '2021m01d03
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Const strLIT_WIKI_MOVE_5_SEC = "Wiki Move 5-Sec"
        Const strvLIT_USER_PROFILE_DOWNLOADS = "%USERPROFILE%\downloads"
        Const strLIT_STAR_DOT_HTM = "WikiMove_*-stamp-*.htm"
        Const strLIT_STAR_DOT_HTML = "WikiMove_*-stamp-*.html"
        Const strLIT_STAR_DOT_CARDTXT = "WikiMove_*-stamp-*.card*.txt"

        Public Shared Sub UITimer_to_Poll_FileDir_And_Move(ur_ret As Strap)
            ur_ret.d("QUIT")
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            Dim strUI_FORM_TITLE = strLIT_WIKI_MOVE_5_SEC
            userbowl_cart.SelKey(uiform_title_bowlname).Contents = strUI_FORM_TITLE
            userbowl_cart.SelKey(enmUN.poll_folder).Contents = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)
            If glbl.gDiagnostics.IsRunningWindow(strUI_FORM_TITLE) Then
                glbl.gInteraction.AppActivate(strUI_FORM_TITLE)

            Else
                Dim objFORM = New Mx.WikiMove_Form()
                objFORM.Text = userbowl_cart.SelKey(enmUN.uiform_title).v(enmUB.contents)
                Call objFORM.Display_FolderList()
                objFORM.tmrFIVE_SEC.Start()
                Dim strNEW_DATA_FOLDER = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)

                'System.Windows.Forms.Application.Run(objFORM) only works from a command line program with no forms open. VBNetScript already has a form open.
                Call objFORM.ShowDialog()
            End If 'gDiagnostics
        End Sub 'UITimer_to_Poll_FileDir_And_Move

        Public Shared Function UITimer_to_Poll_FileDir_And_Move_errhnd(ur_commandline_text As String) As Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Strapd()
            UITimer_to_Poll_FileDir_And_Move_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call UITimer_to_Poll_FileDir_And_Move(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'UITimer_to_Poll_FileDir_And_Move_errhnd

        Public Shared Sub Poll_FileDir_And_Move(ur_ui_form As WikiMove_Form)
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            Dim windows_fs_cart = Have.WindowsFS
            Dim filemove_cart = Have.FileMove
            Call ur_ui_form.Display_FolderList()
            filemove_cart.DelAll()
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTM)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTML)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_CARDTXT)
            filemove_cart.Move_Files()
            Dim report_output_bowlname = userbowl_cart.Apply(filemove_cart)
            Dim strREPORT_OUTPUT = userbowl_cart.SelKey(report_output_bowlname).v(enmUB.contents)
            If HasText(strREPORT_OUTPUT) Then
                ur_ui_form.txtOUTPUT.Text = strREPORT_OUTPUT & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move

        Public Shared Sub Poll_FileDir_And_Move_errhnd(ur_ui_form As WikiMove_Form)
            Dim objERR_LIST = New ErrListBase : Try
                Call Poll_FileDir_And_Move(ur_ui_form:=ur_ui_form)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                ur_ui_form.txtOUTPUT.Text = objERR_LIST.ToString & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move_errhnd

        Public Class CombineTextOutput
            Public gText As Strap
            Public gFolderList As Sdata

            Public Sub New(ur_text As Strap, ur_folder_list As Sdata)
                Me.gText = ur_text
                Me.gFolderList = ur_folder_list
            End Sub
        End Class 'CombineTextOutput
    End Class 'sub_main

    Public Class WikiMove_Form
        Inherits System.Windows.Forms.Form

        Public tmrFIVE_SEC As System.Windows.Forms.Timer
        Public txtOUTPUT As System.Windows.Forms.TextBox
        Public intSHOW_FORM As Integer

        Public Sub New()
            Me.intSHOW_FORM = 1

            Me.Name = "Wiki_Move"
            Me.Size = New System.Drawing.Size(400, 400)
            Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen

            Me.txtOUTPUT = New System.Windows.Forms.TextBox()
            Me.txtOUTPUT.Name = "txtOUTPUT"
            Me.txtOUTPUT.Multiline = True
            Me.txtOUTPUT.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
            Me.txtOUTPUT.Dock = System.Windows.Forms.DockStyle.Fill
            Me.Controls.Add(Me.txtOUTPUT)

            Me.tmrFIVE_SEC = New System.Windows.Forms.Timer()
            Me.tmrFIVE_SEC.Interval = 50
            AddHandler Me.tmrFIVE_SEC.Tick, AddressOf Timer1_Tick
        End Sub 'New

        Sub Display_FolderList()
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            If HasText(Me.txtOUTPUT.Text) = False Then
                Me.txtOUTPUT.Text = Strapd().dLine("Listening:").dS(userbowl_cart.SelKey(pollfolder_bowlname).v(enmUB.contents)).dLine().d(Me.txtOUTPUT.Text)
            End If
        End Sub 'Display_FolderList

        Sub Look_For_Files()
            Call Mx.Want.Poll_FileDir_And_Move_errhnd(Me)
        End Sub

        Sub Show_Saved()
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            If Me.intSHOW_FORM = 1 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Normal
                Call AppActivate(userbowl_cart.SelKey(uiform_title_bowlname).v(enmUB.contents))
                Me.tmrFIVE_SEC.Interval = 800
                Me.intSHOW_FORM = 2

            ElseIf Me.intSHOW_FORM = 2 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Minimized
                Me.intSHOW_FORM = 0

            ElseIf Me.intSHOW_FORM = 0 Then
                If Me.WindowState <> System.Windows.Forms.FormWindowState.Minimized Then
                    Me.intSHOW_FORM = 6
                End If

            Else
                Me.intSHOW_FORM -= 1
            End If
        End Sub 'Show_Saved

        Sub Timer1_Tick(sender As Object, e As System.EventArgs)
            Me.tmrFIVE_SEC.Stop()
            Me.tmrFIVE_SEC.Interval = 5000
            Call Look_For_Files()
            Call Show_Saved()
            Me.tmrFIVE_SEC.Start()
        End Sub 'Timer1_Tick
    End Class 'WikiMove_Form




    Public Class Have
        Partial Class sFileMove
            Public Sub Apply(ur_windows_fs_cart As Have.glblWindowsFS, ur_userbowl_cart As Have.sUserBowl, ur_poll_folder_bowlname As enmUN, ur_filespec As String)
                Dim strPOLL_FOLDER = ur_userbowl_cart.SelKey(ur_poll_folder_bowlname).Contents
                For Each strFILE_PATH In ur_windows_fs_cart.GetFiles(strPOLL_FOLDER, ur_filespec, System.IO.SearchOption.TopDirectoryOnly)
                    Dim flnFILE_NAME = FileNamed().d(strFILE_PATH)
                    Dim sdaEXT_LIST = flnFILE_NAME.ExtList
                    Dim strDEST_PATH_ENCODED_IN_NAME = flnFILE_NAME.Name.Substring("WikiMove_".Length)
                    Dim strDEST_PATH = strDEST_PATH_ENCODED_IN_NAME.Replace("-colon-", ":").Replace("-fslash-", "\")
                    Dim intSTAMP = InStr(strDEST_PATH, "-stamp-")
                    strDEST_PATH = Left(strDEST_PATH, intSTAMP - 1)
                    Dim strEXT = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count))
                    If sdaEXT_LIST.Count > 1 Then
                        Dim strEXT2 = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count - 1))
                        If AreEqual(strEXT, ".txt") AndAlso
                          StartingWithText(strEXT2, ".card") Then
                            strEXT = ".card.txt"
                        End If
                    End If 'sdaEXT_LIST

                    strDEST_PATH &= strEXT
                    Me.Ins(
                        New rFileMove().
                        vt(enmFM.src_file_path, strFILE_PATH).
                        vt(enmFM.dest_file_path, strDEST_PATH)
                        )
                Next strFILE_PATH
            End Sub 'Apply ur_windows_fs_cart

            Public Sub Move_Files()
                Dim lstLEN = New System.Collections.Generic.List(Of Integer)
                For Each rowFILE In Me.SelAll
                    Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                    Dim intLEN = strFILE_PATH.Length
                    If lstLEN.Contains(intLEN) = False Then
                        lstLEN.Add(intLEN)
                    End If
                Next rowFILE

                Call lstLEN.Sort()
                For Each intLEN In lstLEN
                    For Each rowFILE In Me.SelAll
                        Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                        If strFILE_PATH.Length = intLEN Then
                            Dim strDEST_PATH = rowFILE.v(enmFM.dest_file_path)
                            glbl.gWindowsFS.Move(strFILE_PATH, strFILE_PATH & ".TDLY")
                            glbl.gWindowsFS.Delete(strDEST_PATH)
                            glbl.gWindowsFS.Move(strFILE_PATH & ".TDLY", strDEST_PATH)
                        End If 'strFILE_PATH
                    Next rowFILE
                Next intLEN
            End Sub 'Move_Files
        End Class 'sFileMove

        Partial Class sUserBowl
            Public Function Apply(ur_filemove_cart As sFileMove) As enmUN.zreport_output
                Dim retKEY = enmUN.report_output
                Apply = retKEY
                Dim stpREPORT = Strapd()
                For Each rowFILE In ur_filemove_cart.SelAll
                    stpREPORT.dLine(Now.ToString("tt hh:mm:ss")).d(":").dS(rowFILE.v(enmFM.dest_file_path))
                Next rowFILE

                Me.SelKey(retKEY).v(enmUB.contents) = stpREPORT
            End Function 'Apply(ur_filemove_cart
        End Class 'sUserBowl
    End Class 'Have



    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblFileMove As sFileMove
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblFileMove = New sFileMove
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmFM
        Inherits bitBASE
        Public Shared src_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
        Public Shared dest_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
    End Class

    Partial Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function FileMove() As sFileMove
            Call Have.Connect()
            FileMove = Have.tblFileMove
        End Function

        Public Class rFileMove
            Inherits TRow(Of enmFM)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmFM, ur_val As String) As rFileMove
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rFileMove

        Public Class sFileMove
            Private ttb As Objlist(Of rFileMove)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rFileMove)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub DelAll()
                Me.ttb.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rFileMove) As rFileMove
                Ins = ur_from
                Dim ttbSEL = Me
                Me.ttb.Add(ur_from)
            End Function 'Ins

            Public ReadOnly Property SelAll() As Objlist(Of rFileMove)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sFileMove
    End Class 'Have

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared poll_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared uiform_title As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function 'UserBowl

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = Have.WindowsMsgBox.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(strAUDIT)
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

View All Cards

6th March 2021 at 8:06pm
$:/positivesigner/text-ref


AndroidChromeBrowser

DOC

  1. Desktop Shortcut to Website


AndroidChromeBrowser\Desktop Shortcut to Website

AndroidOS Browser FileSystem

This does not work for file:///sdcard HTML files
Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Google Chrome app]
- [Non-incognito mode]
- Navigate to website page
- Note: This does not work for file:///sdcard HTML files
- [Top-right icons]
- Click the three-lines menu, option Add to Home screen -> Opens dialog
- [Add to Home screen dialog]
- Shortcut name / UrShortcutName
- Click button Add -> Closes dialog

[Desktop icons]
- Click icon UrShortcutName -> Opens browser


AndroidGit

DOC

  1. Pocket Git pull repository updates


AndroidGit\Pocket Git pull repository updates

AndroidOS FileSystem GitCode UserAction

[Pocket Git app]
- [Repositories List page, Top-right icons]
- Click button Preferences (looks like three lines) -Navigates page
- [Preferences page, Defaults section]
- Click link Default Directory -> Opens dialog
- [Select Folder dialog]
- Select the Downloads folder -> Closes dialog
- [Preferences page, Defaults section]
- Note: Default Directory = /storage/emulated/0/Download
- Click button Back (looks like a left arrow) -> Navigates page

- [Repositories List page, Bottom-right icons]
- Click button Create Project (looks like a red button with a Plus sign) -> Opens dialog
- [Create Project dialog]
- Project Name = UrProjectName
- Clone URL = UrRepositoryURL
- Note: Local Path automatically creates a sub-directory under the Downloads folder
- Click the Authentication drop-list, option Password
- Username = UrRepositoryUsername
- Password = UrRepositoryPassword
- [Create Project dialog, Top-right icons]
- Click button Save (looks like a floppy disk) -> Closes dialog

- [Repositories List page]
- Click repository UrProjectName -> Navigates page

- [Repository page, Top-right icons]
- Click the Remotes menu (looks like a cloud), click option Fetch -> Starts process
- Wait for popup message "Finished fetching"
- Click the Remotes menu, click option Pull -> Starts process
- Wait for popup message "Finished pulling"

[File system]
- [Downloads folder]
- Note: All the files in the repository are available under the UrProjectName sub-folder in the Downloads folder


AndroidMultipleUsers

DOC

  1. Common access files


AndroidMultipleUsers\Common access files

AndroidOS FileSystem UserAction

When you change users on an Android device, the file:///sdcard/ folder is aliased to a different location for each. There is a specific sub-folder that is aliased to the same location for all users.

[File Manager]
- Navigate to /sdcard/Android/obb
- Create a folder and copy files into it

[Android Notices menu]
- Change the current user

[File Manager]
- Navigate to /sdcard/Android/obb
- You can see the same folder and files from the other login


AndroidProgramming

DOC

  1. DCoder


AndroidProgramming\DCoder

AndroidOS FileSystem VBCode

Note: I found that the DCoder app actually submitted the VB code to a web server. So there was no way for me to access the local file system.

  'Visual Basic.Net Compiler version 0.0.0.5943 (Mono 4.0.1)

Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Namespace Dcoder
  Public Module Program
    Public Sub Main(args() As string)
      Dim strRET = "Hi"
      For Each strENTRY As String In SubDir_List("/")
          For Each strE2 As String In SubDir_List("/" & strENTRY)
          For Each strE3 As String In SubDir_List("/" & strENTRY)
              strRET &= vbLf & strENTRY & "/" & strE2 & "/" & strE3
          Next strE3
          Next strE2
      Next strENTRY
      
      strRET &= vbLf & "Done"
      Console.WriteLine(strRET)
    End Sub 'Main

    Public Function t1(ur_root_dir As String) As String
        Return "no"
    End Function

    Public Function SubDir_List(ur_root_dir As String) As System.Collections.Generic.List(Of String)
      Dim lstRET = New System.Collections.Generic.List(Of String)
      SubDir_List = lstRET
      Try
      Dim proc = New System.Diagnostics.Process
      Dim stg = new System.Diagnostics.ProcessStartInfo
      proc.StartInfo = stg
      stg.FileName = "ls"
      stg.Arguments = ur_root_dir

      'stg.FileName = "find"
      'stg.Arguments = ". -name '*' -print"

      stg.UseShellExecute = false
      stg.RedirectStandardOutput= true
      stg.RedirectStandardError = true
      stg.CreateNoWindow = true
      proc.Start()
      Dim strCL_OUT = proc.StandardOutput.ReadToEnd()
      'strRET = "[Output: " & vbLf & strCL_OUT & "]"
      'strRET &= vbLf & "(err: " & vbLf & proc.StandardError.ReadToEnd() & ")"
      For Each strENTRY As String In strCL_OUT.Split(CHR(10))
          If strENTRY <> "" Then
              lstRET.Add(strENTRY)
          End If
      Next strENTRY
      Catch ex As System.Exception
      End Try
    End Function 'SubDir_List
  End Module
End Namespace

AndroidQLua

DOC

  1. Console Commands
  2. Console Run a Program
  3. Deploy a Program Module
  4. Editor Run a Program
  5. MxClasses Design
  6. MxClasses LoadFile
  7. MxClasses Require Program Module
  8. Source Code Editor


AndroidQLua\Console Commands

AndroidOS CodeLibrary LuaCode

[QLua app]
- Click button Console -> Navigates page

- [console window]
- Note: The right-arrow symbol (greater-than sign) is the Lua prompt
- Note: Comment line-endings in a Lua file are separated by two hyhpens

--Single-line comment
ur_object.ur_function() --Comment until end of line

- Note: Multi-line comments in a Lua file are separated by two hyphens and two open brackets, and closed by two hyphens and two close brackets

--[[
Block comment
multiple lines
--]]

- Note: Commands in Lua are case sensitive
- - You can create functions named abc, Abc, abC, and ABC, and each one can store to a different value

- Note: Exiting the Lua interpreter returns to the Linux Shell command line interpreter that was created by QLua
- Run the os.exit() command

os.exit()

[Linux Shell CLI]
- Note: The $ symbol (dollar sign) is the Linux Shell prompt
- Note: Commands in Linux Shell are case sensitive
- - You can create programs named abc, Abc, abC, and ABC, and each one can run different code
- - Most standard Linux Shell commands are named with all lowercase characters, so only abc would be the standard way to name a program

- Note: Exiting the Linux Shell returns to the QLua app main page
- Run the exit command

exit

AndroidQLua\Console Run a Program

AndroidOS LuaCode UserAction

[Lua console]
- Note: I had problems using the LoadString function with the loadfile command
- - In the Lua code, replace any references to the LoadString function with the Load function
- - The Load command did not need extra escaping like\\r for the parameter, so replace \\r with \r when using the Load command
- Save the result of the loadfile command to create a new function from the file

urfile_fn=loadfile('/sdcard/qlua5/ur_file.lua')

- Note: This added a row to the _G table
- Note: Just typing a function name or a table name shows the type of data stored in the row

_G.urfile

- Output is function: 0x#####
- Note: any command except _G is an implied name lookup in the _G table

urfile

- Output is also the same function: 0x####
- Note: You can run a function by adding parentheses to the end of the function name
- Running a function can load additional functions into the _G table

urfile()

- Output is the Lua program output
- Note: Any functions or tables added to the _G table are available
- Note: You can load a Lua function and run it on the same line instead of storing the program in a variable by adding an extra pair of parentheses

loadfile('/sdcard/qlua5/ur_file.lua')()

- Output is the Lua program output


AndroidQLua\Deploy a Program Module

AndroidOS FileSystem LuaCode

Note: The share/5.3 directory under the QLua5 folder is where Lua looks to load "program modules" that must be loaded to the _G array as a prerequisites to running the current program

[QLua Editor]
- Note: I had problems using the LoadString function with the require command
- - In the Lua code, replace any references to the Load function with the LoadString function
- - The LoadString command needs extra escaping like\\r for the parameter, so replace \r with \\r when using the LoadString command

- [Bottom bar]
- Click button Save-As (Looks like a page with a Plus in the bottom-right corner) -> Open dialog

- [Save As dialog]
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = share
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder share
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = 5.3
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder 5.3
- [Bottom bar]
- File name = UrFileName.lua
- Click button OK (looks like a checkmark)

[File Manager]
- Note: Your Lua program is stored in folder /sdcard/qlua/share/5.3

[Lua console]
- Note: The require command to loads and runs a program module
- - Do not include the path or the .lua file extension

require 'UrFileName'

- Output is the Lua program output


AndroidQLua\Editor Run a Program

AndroidOS LuaCode UserAction

[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icon]
- Click button Open file (looks like a Tabbed folder) -> Opens dialog
- Select file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Note: You can change the source code and save again before each run

- [Bottom bar icons]
- Click button Run (looks like a right-arrow play button) -> Navigates page

- [console window]
- Note: The top line shows the current path and the Linux shell command used to show the editor
- Note: The output of your program is below the first line
- Note: The the last line says "Press enter to exit"


AndroidQLua\MxClasses Design

AndroidOS AssignVariable FileSystem LuaCode

I created some default functions that I need to see the key/value pairs in Lua tables

[def.lua]
- [def_tcompile]
- This creates a 'tcompile' function that concatenates a table's string values then loads the result as a new function
- [def_ti]
- This creates a 'ti' function that adds a new numbered row to a table
- [def_tia]
- This clears out a global table variable and creates a 'tia' function that calls the 'ti' function for that table without having to pass it in as a parameter
- [def_printk]
- This creates a 'printk' function that prints all the keys in a table, sorted alphabetically
- [def_printv]
- This creates a 'printv' function that prints all the values in a table, sorted alphabetically
- [def_tcopy]
- This creates a 'tcopy' function that copies all records from one table into another
- [def_printiv]
- This creates a 'printiv' function that prints all the values in a table, in their original order (good for numeric-keyed tables)
- [def_printkv]
- This creates a 'printkv' function that prints all keys and values in a table, sorted by key alphabetically
- [def_ioexec]
- This creates a 'ioexec' function that runs a shell command and returns a table you can store
- Example: Prints all the .lua files under a directory

local ttbFILE = ioexec('find /sdcard/qlua5 -name "*.lua" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)

- [def_printio] - This creates a 'printio' function that runs printiv on the ioexec table - Example: printio('ls /storage')


AndroidQLua\MxClasses LoadFile

AndroidOS CodeLibrary FileSystem LuaCode
--[under folder /sdcard/qlua5]
--This file can be run by the QLua command "LoadFile" because it uses the Load function instead of the LoadString function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) load(table.concat(ur_table, "\\r"))() end'}
load(table.concat(def_tcompile, "\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  load(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)

AndroidQLua\MxClasses Require Program Module

AndroidOS CodeLibrary LuaCode
--[under folder /sdcard/qlua5]
--Create subdir share/5.3
--Put in a copy of def.lua
--This file can be run by the QLua command "require" because it uses the LoadString function instead of the Load function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) loadstring(table.concat(ur_table, "\\r"))() end'}
loadstring(table.concat(def_tcompile, "\\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  loadstring(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
--[[
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)
--]]

AndroidQLua\Source Code Editor

AndroidOS LuaCode UserAction

[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icons]
- Click button New File (looks like a page with a Plus sign) -> Opens dialog

- [New file dialog]
- Click option Blank file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Enter some text

- [Bottom bar]
- Click button Save (looks like a 3.5" floppy disk)

[SDCard file list]
- Note: The file gets saved in the folder /sdcard/qlua5


AndroidScreenshot

DOC

  1. Screenshot Easy


AndroidScreenshot\Screenshot Easy

AndroidOS Extract Video

[Google Play Store app]
- Install app Screenshot Easy by Ice Cold Apps
- Note: Contains ads


AndroidVNC

DOC

  1. RealVNC remote control Windows O/S
  2. Remote Control Android Device


AndroidVNC\RealVNC remote control Windows O/S

AndroidOS UserAction Video WindowsOS

Windows O/S

[https://www.realvnc.com/en/connect/download/viewer/windows/]
- Install app VNC Connect for Windows

[VNC Connect for Windows app]
- Connects to login
- Note: Allows connection by RealVNC's VNC Viewer app on Android O/S

Android O/S

[Google Play Store]
- Install app VNC Viewer by RealVNC Limited

[VNC Viewer app]
- Connects to login
- [Alt tab]
- Use Ctrl-Esc to get to the Windows Start Menu and the Task Bar to change windows


AndroidVNC\Remote Control Android Device

AndroidOS UserAction Video

Install app AnyDesk by AnyDesk Software GmbH
- https://play.google.com/store/apps/details?id=com.anydesk.anydeskandroid&hl=en_US&gl=US

Install on both Android devices
- The other installed devices will show when connected to the same WiFi network
- Automatically figures out how to use the controlling Android device's touch screen


AndroidWebDav

DOC

  1. BestDAV


AndroidWebDav\BestDAV

AndroidOS FileSystem UserAction

Access files on Android device from a networked Windows computer

[Andrdoid OS]
- [Google Play Store]
- Install app WebDAV Server - BestDAV
- - Free or Pro edition

[WebDAV Server]
- [Main page, top bar]
- Note: Folders not listed under the "Folders" button automatically has read-only access via WebDav
- Click button Settings -> nav
- [Settings page]
- Website Home Directory = /storage
- [Main page, bottom bar]
- Click button Start Server
- Note: The server's network URL starts with "http://" and ends with ":8080"
- - Sample = http://192.168.0.15:8080

[Windows computer]
- [browser]
- Address = http://192.168.0.15:8080
- Click link Get the file list -> nav
- Note: The directory shows the "external" SD Card name (if any) and "enc_emulated"
- To see the "internal" /sdcard folder on the android device,
- - Click link "enc_emulated" -> /_dir.cgi?dir=%2Fenc_emulated
- - Edit the address to say /_dir.cgi?dir=%2Femulated/0

- [Windows Explorer]
- Address = \\192.168.0.15@8080\DavWWWRoot
- Note: The directory shows the "external" SD Card name (if any) and "emulated", "enc_emulated", and "self"
- To see the "internal" /sdcard folder on the android device,
- - Click link "emulated" -> http://192.168.0.15:8080/emulated
- - Edit the address to say http://192.168.0.15:8080/emulated/0


btn Delete Cards

$:/positivesigner/base-install


ChromeBrowser

DOC

  1. Browse Local Folders
  2. Command Line Options
  3. Turn off Chrome spell check highlighting


ChromeBrowser\Browse Local Folders

Browser Extract FileSystem

Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome

[Google Chrome app]
- [Windows O/S]
- Navigate to file:///C:/
- [Android O/S]
- Navigate to file:///sdcard/

- [Directory list]
- Select which sub-folder you want to bookmark
- [Navigation bar, Top-right icons]
- Click button Bookmark Page (looks like a star shape) -> Opens dialog
- [Bookmark Added dialog]
- Name = UrShortName
- Click button Done -> Closes dialog
- [Navigation bar]
- Address = UrShortName -> Shows suggestions
- [Suggestion list]
- Select the suggested link -> Navigates page


ChromeBrowser\Command Line Options

AssignVariable Browser CodeLibrary

The command line options are usually two hyphens followed by a keyword

- Note: The incognito option starts the browser with an open Incognito window

–incognito

- Note: Google Chrome Portable has these parameters automatically included when calling the Chrome.exe program.

–user-data-dir="%TEMP%"
–disk-cache-dir="%TEMP%\GoogleChromePortable\Cache"

To override the user data and all the cache directories:

- Find the INI file in the PortableApp sub-directory

GoogleChromePortable\Other\Source\GoogleChromePortable.ini

- Copy it to the program main directory

GoogleChromePortable\GoogleChromePortable.ini

- [Edit the file]
- CacheInTemp = false
- Save file
- Note: When you restart Google Chrome Portable, cached files will be stored under the program's folder

C:\TJBF\zPortableInstalls\Chrome\Data\profile\Default\*Cache\

ChromeBrowser\Turn off Chrome spell check highlighting

Browser CodeLibrary Formatting Text

[Google Chrome app]
- [Top-right icons]
- Click the three-dots menu, option Settings -> Navigates page
- [Settings page[
- search for Language -> Filters results
- [Languages section]
- checkbox Spell check = clear -> Chrome will not highlight spelling errors


DivPop btn

$:/positivesigner/div-pop $:/tags/ViewToolbar


DivPop glbl

$:/positivesigner/div-pop $:/tags/BelowStory


Excel VBA

DOC

  1. Get Worksheet
  2. New Macro
  3. Power Exponent


Excel VBA\Get Worksheet

CodeLibrary ExcelCode FileSystem
Dim wksDATA As Worksheet
Set wksDATA = Application.ActiveSheet
wksDATA.Cells(2,2).Value = "Hi"

'Press F5 to run the macro
'Note: Cell B2 says "Hi"

Excel VBA\New Macro

AssignVariable ExcelCode FileSystem

[Microsoft Excel application]
- [Ribbon menus]
- View menu, option Record Macro -> Starts recording
- View menu, option Stop Recording -> Stops recording
- View menu, option Macros -> Opens dialog

[Macro list]
- Click button Edit Macro -> Opens window

[VBA Editor]
- You can change the name of the macro and add commands
- Close the editor

[Microsoft Excel application]
- Save the file as a Macro-Enabled workbook (mwb)


Excel VBA\Power Exponent

ExcelCode Extract Numbers

Make sure you put a space between the power operator (^) and the numbers

- CalcResult = 2^5
- Note: This gives a compilation error on 64-bit Excel

- CalcResult = 2 ^ 5
- Note: CalcResult = 32


ext ALAorg Citations bookmarklet

EXT

http://www.ala.org/tools/article/ala-techsource/%E2%80%9Ccitethis%E2%80%9D-building-javascript-bookmarklet-creates-citations-sharing-web


ext Apple.com Safari Meta tags

EXT

https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html


ext CodeAcademy DocType

EXT

https://discuss.codecademy.com/t/why-we-type-before-doctype-what-is-the-role-of-in-doctype-html/60880/3


ext DeveloperSettings HTM

EXT

VBNet_Project\DeveloperSettings\Developer Settings App.html


ext DeveloperSettings ZIP

EXT

VBNet_Project\DeveloperSettings\DeveloperSettings.zip


ext Empty Wiki Setup

EXT

TW Project\Empty Wiki\Empty Wiki.htm


ext FileFormat.Info UnicodeInput

EXT

https://www.fileformat.info/tool/unicodeinput/index.htm


ext FileFormat.Info UnicodeInput.ZIP

EXT

https://www.fileformat.info/tool/unicodeinput/unicodeinput.zip


ext GitHub LukeHorvat Computed Style to Inline

EXT

https://github.com/lukehorvat/computed-style-to-inline-style


ext GoogleDevelopers FullScreen web app

EXT

https://developers.google.com/web/fundamentals/native-hardware/fullscreen/


ext HTML.com DocType

EXT

https://html.com/tags/doctype/


ext JavaScript Closures

EXT

http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html


ext JavaScript Strict Mode

EXT

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode


ext JavaScript This Parameter

EXT

http://blog.niftysnippets.org/2008/03/mythical-methods.html


ext JTFAssociates MOTW

EXT

https://jtfassociates.com/using-the-mark-of-the-web-motw/


ext MathiasBynens Rel Icon

EXT

https://mathiasbynens.be/notes/rel-shortcut-icon


ext MetaTags.org Generator

EXT

https://www.metatags.org/all-meta-tags-overview/meta-name-generator/


ext Microsoft DotNet Char ConvertToUTF32

EXT

https://docs.microsoft.com/en-us/dotnet/api/system.char.converttoutf32?view=net-5.0#System_Char_ConvertToUtf32_System_String_System_Int32_


ext Microsoft RemoteDesktop Enable

EXT

https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-allow-access


ext Mozilla.org META tags

EXT

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name


ext MozillaDeveloper CSS Comment

EXT

https://developer.mozilla.org/en-US/docs/Web/CSS/Comments


ext MozillaDeveloper Strict mode

EXT

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode


ext MxBase Classes

EXT

VBNet_Project/MxBase/MxBase%20Classes.html


ext Project Check app

EXT

TW Project\Checkapp\Checkapp.htm


ext PSU.edu LangTag

EXT

https://accessibility.psu.edu/foreignlanguages/langtaghtml/


ext Regexp Filter with brackets

EXT

https://tiddlywiki.narkive.com/T5403O4p/tw5-regexp-for-matching-a-tag-tiddlytweeter#post7


ext Regular Expression Quantifiers

EXT

https://www.rexegg.com/regex-quantifiers.html


ext Roman to Decimal ZIP

EXT

VBNet_Project\Examples\Roman_To_Decimal.zip


ext Shuffle List Entries

EXT

TiddlyWiki_Code\Snapshot\mklauber TWPlugin Shuffle.txt.html


ext SitePoint Exports Node.JS

EXT

https://www.sitepoint.com/understanding-module-exports-exports-node-js/


ext SO.com RunTime Net 4.5

EXT

https://stackoverflow.com/questions/8517159/how-do-i-detect-at-runtime-that-net-version-4-5-is-currently-running-your-code


ext SQLite Blob text

EXT

https://stackoverflow.com/questions/15366594/convert-hex-to-text-using-sqlite


ext SQLite DB Browser

EXT

https://sqlitebrowser.org/dl/


ext SQLite Language functions

EXT

https://sqlite.org/lang_corefunc.html


ext SQLite schema information

EXT

https://stackoverflow.com/questions/6460671/sqlite-schema-information-metadata


ext SQLite Top 5 Records

EXT

https://stackoverflow.com/questions/2728999/how-to-get-top-5-records-in-sqlite


ext StackOverflow CSS location

EXT

https://stackoverflow.com/questions/1642212/whats-the-difference-if-i-put-css-file-inside-head-or-body


ext StackOverflow Hide Parent Show Child tag

EXT

https://stackoverflow.com/questions/12956937/display-html-child-element-when-parent-element-is-displaynone


ext StackOverflow Meta UA-Compatible

EXT

https://stackoverflow.com/questions/6771258/what-does-meta-http-equiv-x-ua-compatible-content-ie-edge-do#:~:text=The%20X%2DUA%2DCompatible%20meta%20tag%20allows%20web%20authors%20to,meta%20tag%20in%20certain%20circumstances.


ext Tiddly Wiki Home Button source code

EXT

https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/PageControls/home.tid


ext TiddlyWiki Save Button source code

EXT

https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/PageControls/savewiki.tid


ext TiddlyWiki TopBar Menu

EXT

https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/TopRightBar/menu.tid


ext TW Addon Text Replace

EXT

TiddlyWiki_Code\AddOns\Text Replace Bar.htm


ext TW Create Javascript Plugin

EXT

https://sudonull.com/post/97468-How-to-write-a-plugin-for-TiddlyWiki


ext TW Features

EXT

TiddlyWiki_Code\Features\TW Features.htm


ext TW JS Pretty

EXT

TW Project\JS_Pretty\TW JS Pretty.htm


ext TW Manual

EXT

TiddlyWiki_Code\Snapshot\TheBook - The TiddlyWiki Manual.txt.html


ext TW Return

$:/positivesigner/text-ref

(TiddlyWiki view of website)


ext TW Snapshot Review

EXT

TiddlyWiki_Code\Snapshot\Browse Code tiddlywiki_v5d01d23pre-release.htm


ext TW Snapshot v5d01d23 empty

EXT

TW Project\Snapshot\tw_empty_v5d01d23.html


ext TW Snapshot v5d01d23 main-site

EXT

TW Project\Snapshot\tiddlywiki_v5d01d23_main-site.html


ext TW Snapshot v5d01d23 pre-release

EXT

TW Project\Snapshot\tiddlywiki_v5d01d23_pre-release.html


ext TW Snapshot v5d01d23 update

EXT

TW Project\Snapshot\tiddlywiki_v5d01d23_update.html


ext Unicode Block 00-Basic Latin

EXT

https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)


ext Unicode Block 01-Latin Supplement

EXT

https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)


ext Unicode Block Planes

EXT

https://en.wikipedia.org/wiki/Plane_(Unicode)


ext Unicode Character Database

EXT

http://www.unicode.org/Public/UCD/latest/


ext Unicode Code Block List

EXT

https://en.wikipedia.org/wiki/Unicode_block


ext VBNetScript.EXE

EXT

VBNet_Project\VBNetscript\VBNetScript_EXE.zip


ext VBNetScript.SLN

EXT

VBNet_Project\VBNetscript\VBNetScript_Project.zip


ext W3.org HTML401 Meta

EXT

https://www.w3.org/TR/html401/struct/global.html#h-7.4.4


ext W3.org HTML401 Profiles

EXT

https://www.w3.org/TR/html401/struct/global.html#profiles


ext W3Schools DocType

EXT

https://www.w3schools.com/tags/tag_doctype.asp


ext W3Schools Head tag

EXT

https://www.w3schools.com/tags/tag_head.asp


ext W3Schools Meta HTTP-EQUIV

EXT

https://www.w3schools.com/tags/att_meta_http_equiv.asp


ext W3Schools NoScript tag

EXT

https://www.w3schools.com/tags/tag_noscript.asp


ext WestWindCom Net Core Runtime

EXT

https://weblog.west-wind.com/posts/2018/Apr/12/Getting-the-NET-Core-Runtime-Version-in-a-Running-Application


ext WHATWg.org Link Icon

EXT

https://html.spec.whatwg.org/multipage/links.html#rel-icon


ext Wiki Move HTM

EXT

VBNS_Project\Wiki_Move\Wiki Move HTM.htm


ext Windows Alt-Numpad Unicode

EXT

https://conemu.github.io/en/AltNumpad.html


ext Windows Environment Variable List

EXT

https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables#bkmk-1


ext Windows Terminal Unicode Support

EXT

https://devblogs.microsoft.com/commandline/introducing-windows-terminal/


ext WindowsCLI Unicode Support

EXT

https://www.generacodice.com/en/articolo/203149/How-to-use-unicode-characters-in-Windows-command-line


FFMPeg

DOC

  1. Extract Captions file
  2. Extract JPG files


FFMPeg\Extract Captions file

Extract Text WindowsOS
chcp 65001
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" "C:\UrPath\UrFile.srt"
pause

FFMPeg\Extract JPG files

Extract Video WindowsOS

[ffmpeg.exe command-line options]
- -ss 05:00 -t 10:00 means start at 5min and end 10min later at 15min
- -r 1 means 1 frame per second
- -r 0.25 means 1 frame every 4 seconds
- -r 0.083 means 1 frame every 12 seconds, or 5 frames per minute, 50 frames out of every ten minutes, or 300 frames every hour

- IrfanView can create a portrait contact sheet with 5 columns, representing one min of video per row, 10 rows per page showing 10 minutes of video
- IrfanView can create a landscape contact sheet with 7 columns is one 3 min per 2 rows, 7 rows per page showing 10.5 minutes of video, two pages showing 21 minutes

- Open on thumbnail image with IrfanView, select File menu Thumbnails option
- Select all files in the folder, select File menu Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

chcp 65001
rem -ss 05:00 -t 10:00 means start at 5min and end 10min later at 15min
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" -r 0.083 -s 320x180 "UrPath\UrSubdir\output_%%04d.jpg"


Font Size

$:/positivesigner/text-ref

Specific prefix filter: 334 cards

Non-system plus system PositiveSigner filter: 334 cards



Panel

Cards where has[tags] does not work

Cards with no tags

parm SkipSaveExportHTML

btn Delete Cards


GitCLI

DOC

  1. Checkout hash


GitCLI\Checkout hash

Extract FileSystem GitCode
@echo off
SET ur_repo=
SET ur_branch=
"C:\UrPath\git.exe" -C %ur_repo% checkout -b test-branch %ur_branch%

rem Use GitHub Desktop to delete the branch

GitHubDesktop

DOC

  1. Git executable


GitHubDesktop\Git executable

FileSystem GitCode WindowsOS

When GitHub Desktop is installed, the Git.exe program is placed in the %APPDATA% folder. There is one sub-directory for each version of Git that has been downloaded. Look for the latest version-numbered folder.

C:\Users\UrUser\AppData\Local\GitHubDesktop\app-UrVersion

Under the app-UrVersion folder, find the Git.exe program

app-UrVersion\resources\app\git\cmd\git.exe

GoogleContacts

DOC

  1. Export as CSV


GoogleContacts\Export as CSV

Extract FileSystem Service

[https://contacts.google.com/]
- [Left-side menu]
- Click button Export -> Opens dialog
- Export contacts = Contacts (total count)
- Export as = Google CSV
- Click button Export -> Downloads file, Closes dialog

[CSV file]
- Header fields =

Name
Given Name
Additional Name
Family Name
Yomi Name
Given Name Yomi
Additional Name Yomi
Family Name Yomi
Name Prefix
Name Suffix
Initials
Nickname
Short Name
Maiden Name
Birthday
Gender
Location
Billing Information
Directory Server
Mileage
Occupation
Hobby
Sensitivity
Priority
Subject
Notes
Language
Photo
Group Membership
E-mail 1 - Type
E-mail 1 - Value
E-mail 2 - Type
E-mail 2 - Value
Phone 1 - Type
Phone 1 - Value
Phone 2 - Type
Phone 2 - Value
Address 1 - Type
Address 1 - Formatted
Address 1 - Street
Address 1 - City
Address 1 - PO Box
Address 1 - Region
Address 1 - Postal Code
Address 1 - Country
Address 1 - Extended Address
Organization 1 - Type
Organization 1 - Name
Organization 1 - Yomi Name
Organization 1 - Title
Organization 1 - Department
Organization 1 - Symbol
Organization 1 - Location
Organization 1 - Job Description
Relation 1 - Type
Relation 1 - Value
Website 1 - Type
Website 1 - Value

- Header line =

Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initials,Nickname,Short Name,Maiden Name,Birthday,Gender,Location,Billing Information,Directory Server,Mileage,Occupation,Hobby,Sensitivity,Priority,Subject,Notes,Language,Photo,Group Membership,E-mail 1 - Type,E-mail 1 - Value,E-mail 2 - Type,E-mail 2 - Value,Phone 1 - Type,Phone 1 - Value,Phone 2 - Type,Phone 2 - Value,Address 1 - Type,Address 1 - Formatted,Address 1 - Street,Address 1 - City,Address 1 - PO Box,Address 1 - Region,Address 1 - Postal Code,Address 1 - Country,Address 1 - Extended Address,Organization 1 - Type,Organization 1 - Name,Organization 1 - Yomi Name,Organization 1 - Title,Organization 1 - Department,Organization 1 - Symbol,Organization 1 - Location,Organization 1 - Job Description,Relation 1 - Type,Relation 1 - Value,Website 1 - Type,Website 1 - Value

- Sample data 1

.me,.me,,,,,,,,,,,,,,,,,,,,,,,,,,,Imported 8/5/16 ::: * myContacts,,,,,Mobile,5554443333 ::: 16665554444,,,,,,,,,,,,,,,,,,,,,,,

- Sample data 2

UrContactName,UrContactFirstName,,UrContactLastName,,,,,,,,,,,,,,,,,,,,,,,,,* myContacts,,,,,Mobile,(444) 333-2222,,,,,,,,,,,,,,,,,,,,,,,

GoogleGmail

DOC

  1. Export as MBOX
  2. MBOX file parsing test


GoogleGmail\Export as MBOX

Extract FileSystem Service

[https://takeout.google.com/]
- [Products section]
- Click link Deselect All
- [Mail section]
- checkbox = set
- [End of Page section]
- Click button Next Step -> Navigates section
- [Choose file type, frequency & destination]
- Frequency = Export once
- File type = .zip
- File size = 2 GB
- Click button Create Export -> Navigates section
- [Export Progress]
- Note: Google is creating a copy of files from Mail. This process can take a long time (possibly hours or days) to complete. You'll receive an email when your export is done.

[https://mail.google.com/]
- [Message with title "Archive of Google data requested"]
- Note: You can ignore the message or click the link to verify it was you
- [Message with title "Your Google data is ready to download"]
- Click button Download Your Files -> Opens tab

[Google Takeout form]
- Re-enter your password
- [Record where Export = Mail]
- Note: The size of the export file is also in the Export column
- Click button Download -> Downloads file
- Note: The file may take a long time to download depending on your internet connection and the size of the file

[ZIP file]
- Extract the ZIP file to a folder

[Takeout folder]
- Open the archive_browser.html -> Opens browser

[Archive Browser page]
- [File Formats tab]
- Note: An mbox is a way of storing mail messages and is supported by common mail clients like Microsoft Outlook, Mozilla Thunderbird, and Apple's Mail program. These files are most easily opened by a dedicated mail client like those listed above

[Takeout\Mail folder]
- [All mail Including Spam and Trash.mbox]
- Use Mozilla Thunderbird to read the MBOX file
- OR Split this file into smaller text files... somehow
- Format:

Record Start = Leading "From " <- Including the space
Tags = "WordsWithoutSpaces:" <- no spaces in tag name
Tag continuation values = " Every Line With Leading Space Or Tab After Tag Name"
Email Content = "First line that is not a tag or tag continuation -> through last line before next leading " "From "


GoogleGmail\MBOX file parsing test

Extract Service Text
start "" "%~dp0\MxClasses\VBNetScript.exe" /path=%0 & exit
MxClasses\MxBaseEc12.vb
RetVal = Mx.Want.TextFile_Split_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.TextFile_Split_errhnd
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub TextFile_Split(ret_message As Strap)
			Dim tabchr = CHR(9)
			Dim flnDATA = FileNamed().d("C:\Users\Dad\Downloads\Takeout\Mail\All mail Including Spam and Trash.mbox")
			Dim intLINE_COUNT = 0
			Dim sdaPREFIX_SKIPPED = New Sdata
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), False, gUTF8_FileEncoding)
				Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
				    Dim bolINCLUDE_INDENTED_LINES = False
					Dim bolHTML_TEXT = False
					Dim bolPLAIN_TEXT = False
					Dim bolSKIP_TEXT = False
					While stmDATA.EndOfStream = False
						Dim strLINE = stmDATA.ReadLine()
						If strLINE.Length = 0 Then
						
						ElseIf Left(strLINE, 5) = "From " AndAlso
						  Len(strLINE) = 59 Then
						    bolINCLUDE_INDENTED_LINES = False
							bolHTML_TEXT = False
							bolPLAIN_TEXT = False
							bolSKIP_TEXT = False
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine(strLINE)
							intLINE_COUNT += 1
						
						ElseIf bolSKIP_TEXT Then
						
						ElseIf bolPLAIN_TEXT Then
							If strLINE.Trim.Length > 0 Then
								Dim bolCUR_HTML = False
								Dim intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									bolCUR_HTML = True
									
									End If
								
								If Left(strLINE, 16) = "X-Attachment-Id:" OrElse
								  Left(strLINE, 32) = "Content-Transfer-Encoding:base64" Then
									bolSKIP_TEXT = True
									
									End If 'strLINE
								
								If bolHTML_TEXT = False Then
									stmOUT_FILE.WriteLine(strLINE)
									intLINE_COUNT += 1
								
								ElseIf bolCUR_HTML Then
									Dim strTEXT = strLINE
									While intFOUND_SPRTR > 0
										Dim strPREFIX = Mid(strTEXT, 1, intFOUND_SPRTR - 1)
										Dim strTAG = Mid(strTEXT, intFOUND_SPRTR)
										intFOUND_SPRTR = InStr(strTAG, ">")
										If intFOUND_SPRTR = 0 Then
											strTEXT = strPREFIX
										
										Else
											strTEXT = strPREFIX & Mid(strTAG, intFOUND_SPRTR + 1)
											intFOUND_SPRTR = InStr(strTEXT, "<")
											
											End If 'intFOUND_SPRTR
										
										End While 'intFOUND_SPRTR
									
									If strTEXT.Trim.Length > 0 Then
										stmOUT_FILE.WriteLine(strTEXT)
										intLINE_COUNT += 1
										
										End If
									
									End If 'intFOUND_SPRTR
									
								End If 'strLINE
							
						ElseIf (Left(strLINE, 1) = s OrElse Left(strLINE, 1) = tabchr) AndAlso
						  bolINCLUDE_INDENTED_LINES Then
							'stmOUT_FILE.WriteLine(strLINE)
							'intLINE_COUNT += 1
						    
						Else 'strLINE
						    bolINCLUDE_INDENTED_LINES = False
							Dim strPREFIX = mt
						    Dim intFOUND_SPRTR = InStr(strLINE, ":")
							If intFOUND_SPRTR > 0 Then
							    strPREFIX = Mid(strLINE, 1, intFOUND_SPRTR)
								If InStr(strPREFIX, tabchr) > 0 OrElse
								  InStr(strPREFIX, s) > 0 Then
									strPREFIX = mt
									
									End If
								
								End If
							
							If strPREFIX = "Content-Type:" OrElse
							  strPREFIX = "Subject:" OrElse
							  strPREFIX = "To:" OrElse
							  strPREFIX = "Date:" OrElse
							  strPREFIX = "From:" Then
								bolINCLUDE_INDENTED_LINES = True
								stmOUT_FILE.WriteLine(strLINE)
								intLINE_COUNT += 1
							
							ElseIf Right(strPREFIX, 1) = ":" Then
								bolINCLUDE_INDENTED_LINES = True
								If sdaPREFIX_SKIPPED.Contains(strPREFIX) = False Then
									sdaPREFIX_SKIPPED.d(strPREFIX)
									
								    End If
							
							ElseIf strPREFIX = "" Then
							    bolPLAIN_TEXT = True
								intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									
									End If
								
								End If 'strPREFIX
							
							End If 'strLINE
						
						If intLINE_COUNT >= 100000 Then
							Exit While
							
							End If
						
						End While 'stmDATA
					
					End Using 'stmDATA
				
				End Using 'stmOUT_FILE
			
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("PREFIX_SKIPPED.TXT"), False, gUTF8_FileEncoding)
				Call sdaPREFIX_SKIPPED.Sort()
				For Each strENTRY In sdaPREFIX_SKIPPED
					stmOUT_FILE.WriteLine(strENTRY)
					
					Next strENTRY
				
				End Using 'stmOUT_FILE

			ret_message.Clear.d(intLINE_COUNT.ToString)
			
			End Sub 'TextFile_Split

        Public Shared Function TextFile_Split_errhnd() As Strap
            Dim stpRET = Strapd()
            TextFile_Split_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call TextFile_Split(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'TextFile_Split_errhnd
    End Class 'Want
End Namespace 'Mx

GooglePlay

DOC

  1. Share purchased apps with another account


GooglePlay\Share purchased apps with another account

FileSystem Service UserAction

[Play Store app]
- [Top-left icon]
- Click the three-lines menu, option Family Library -> Navigates page
- Note: There are two Sections
- - Added by [Other]
- - Added by you

If the purchased app you want to share is not shown under the Added by You section, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option My apps & games -> Navigates page
- [Installed tab, or Library tab]
- Choose an app you purchased -> Navigates page
- [App page]
- Note: The checkbox Family Library is a toggle switch
- checkbox Family Library = set -> The app is available to all Family logins

If the 'Family' logins does not contain the account you want to access your shared app, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option Account -> Navigates page
- [Family tab]
- Click button Manage family members -> Opens dialog
- [Family dialog]
- Click button Invite family members -> Opens dialog
- [Verify CVC dialog]
- Enter your credit card number's CVC number
- Click button Verify -> Closes dialog, Opens dialog
- [Send Invitations dialog]
- Select a contact
- Click button Send

[Added Account email]
- Click the invitation link -> Navigates page
- Note: The Added Account can now use the Play Store app to install the Family Library shared app


GooglePlusCodes

DOC

  1. Find a Plus Code


GooglePlusCodes\Find a Plus Code

Extract FileSystem Numbers Service

[https://plus.codes/map/]
- [Search box, Left-side icon]
- Click the three-lines menu, option Satellite -> Refreshes window
- Click the three-lines menu, option Grid -> Refreshes window
- [Navigate to location]
- When the mouse icon is a hand, double-click to Zoom in
- Each time you click, the location will show as 8 characters, a plus sign, and two suffix characters
- - Example: 73F6C9JH+HR
- The last two Zoom levels allow you to select a single Plus Code rectangle, which has three suffix characters after the plus sign
- - Example: 73F6C9JH+HR7
- Copy the browser address bar
- - Example: https://plus.codes/73F6C9JH+HR7

- Note: You can email the page link to someone
- - They will have to turn on the satellite and / or grid options again

- Note: You can use the browser to bookmark the current page
- - Android O/S Chrome can create a desktop shortcut to the current website page (when not in Incognito mode)

- Note: The plus codes are 8 characters, a plus, and two or three suffix characters
- - The bottom of the Plus.Codes website's map only temporarily shows the three suffix characters after you click, quickly reverting to show only two suffix characters
- - You can still see all three suffix characters in the address bar

- [Bottom location code bar, Right-side icon]
- Click button Navigate (looks like a Right-Turn Only road sign) -> Navigates to Google Maps website
- Note: Android O/S Chrome app will ask to Stay On Web or Use The App
- - Click button Use The App to open the Google Maps app


HTML CSS

DOC

  1. Comment Declaration
  2. Comment MOTW Declaration
  3. Compatibility Meta tags
  4. CSS Style definitions
  5. Declare document Content type
  6. DocType Declaration
  7. Head section
  8. Hide content
  9. HTTP-EQUIV Document Type
  10. iFrame to Local HTML file
  11. Language attribute on tags
  12. META Tag names
  13. Meta Tag Schema
  14. Noscript alternate content
  15. Padding and Margin
  16. Table Rows Alternate
  17. Website icon


HTML CSS\Comment Declaration

HTMLCode Text

HTML 5 document

  • Declaration Name = --
  • Content = unprocessed text, except for the character sequence double-hyphen close-tag ( --> )
  • Note: HTML declarations are not tags, because the have an exclamation mark ( ! ) before the declaration name / code
  • Note: XML documents have a requirement that a double-hyphen ( -- ) must itself be doubled ( ---- ) when used in a comment declaration, but HTML 5 has no such requirement

Sample code for HTML 5 Comment

<!-- a text editor can see the comment text -->

HTML CSS\Comment MOTW Declaration

Browser HTMLCode Text

HTML document viewed in Internet Explorer

  • Comment text sequence:
  • <!-- and optional whitespace
  • saved from url=(
  • the number of characters in the URL string (including the trailing backslash)
  • )
  • the URL string
  • optional whitespace and -->
  • HTML documents viewed in Internet Explorer show a warning message due to active content, or has a specifically crafted HTML Comment Declaration that names the root URL of the website it is being hosted on
  • Note: If this is for a new site, or if the domain is not known, you can use about:internet as a valid URL

JTFAssociates MOTW

->

Sample code

<!-- saved from url=(0014)about:internet -->

HTML CSS\Compatibility Meta tags

Browser Formatting HTMLCode

Declare compatibility version of Microsoft Internet Explorer web browser

  • tag name = meta
  • http-equiv attr = X-UA-Compatible
  • content attr = IE=Edge or (IE=11, IE=EmulateIE11, and similar version number pairs)
  • Note: Use this tag if you need features specific to an older version of IE like IE9 or IE8
  • Note: If you only support the latest browsers (IE11 and/or Edge) then this tag will not affect the web page's behavior until another version is created

Internet Explorer begins interpreting markup using the latest version. When Internet Explorer encounters the X-UA-Compatible META tag it starts over using the designated version's engine. This is a performance hit because the browser must stop and restart analyzing the content.

StackOverflow Meta UA-Compatible

->

Sample code

<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>

content="IE=Edge" mode tells Internet Explorer to display content in the highest mode available. With Internet Explorer 9, this is equivalent to IE9 mode. If a future release of Internet Explorer supported a higher compatibility mode, pages set to edge mode would appear in the highest mode supported by that version. Those same pages would still appear in IE9 mode when viewed with Internet Explorer 9.

Specify web application runs in full-screen mode on Apple devices

  • tag name = meta
  • name attr = apple-mobile-web-app-capable
  • content attr = yes
  • Note: The default behavior is to use Safari to display web content
  • Note: You can determine whether a webpage is displayed in full-screen mode using the window.navigator.standalone Boolean JavaScript property

Apple.com Safari Meta tags

->

Sample code

Specify the Full Screen's status bar style on Apple devices

  • tag name = meta
  • name attr = apple-mobile-web-app-status-bar-style
  • content attr = default, black, black-translucent
  • Note: If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar
  • Note: This meta tag has no effect unless you first specify full-screen mode as described in apple-apple-mobile-web-app-capable

Apple.com Safari Meta tags

->

Sample code

<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

Leave original formatting of telephone-number formatted strings

  • tag name = meta
  • name attr = format-detection
  • content attr = telephone=no
  • Note: By default, Safari on iOS detects any string formatted like a phone number and makes it a link that calls the number

Apple.com Safari Meta tags

->

Sample code

<meta name="format-detection" content="telephone=no" />

Specify web application runs in full-screen mode on Apple devices

  • tag name = meta
  • name attr = mobile-web-app-capable
  • content = yes
  • Note: This tells the browser to launch the page fullscreen when the user has added it to the home screen
  • Note: A better option is to use the Web App Manifest for Chrome, Opera, Firefox, and Samsung browsers

GoogleDevelopers FullScreen web app

->

Sample code

<meta name="mobile-web-app-capable" content="yes"/>

HTML CSS\CSS Style definitions

Browser CSSCode FileSystem

Place a CSS style-sheet in the HTML document

  • tag name = style
  • type attr = text/css
  • Note: The most recent versions of the HTML spec now permits the <style> tag within body elements
  • Note: Putting CSS in body means it is loaded later and the browser starts drawing the interface faster
  • Note: Putting CSS in body can decrease page performance due to possible reflows/repaints once the browser hits styles further down in the page tree

StackOverflow CSS location

->

Sample code

<style type="text/css">

Place a comment inside of a CSS style-sheet

  • Start CSS comment text with forward-slash asterisk ( /* )
  • End CSS comment text with asterisk forward-slash ( */ )

MozillaDeveloper CSS Comment

->

Sample code

<style type="text/css">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>

HTML CSS\Declare document Content type

Browser HTMLCode Text

HTML CSS\DocType Declaration

EXT

HTML 5 document

  • Declaration Name = DOCTYPE
  • Content = html
  • Note: HTML declarations are not tags, because the have an exclamation mark ( ! ) before the declaration name / code
  • Note: This should be the first non-whitespace characters in the document to be compliant with HTML standards
  • Note: HTML5 documents don't really need a DOCTYPE as there is no HTML5 DTD for browsers to refer to, but it is used in HTML5 to make sure the browser doesn’t switch into “quirks” mode and remains in full standards mode

W3Schools DocType

->

HTML.com DocType

->

CodeAcademy DocType

->

Sample code for HTML 5 declaration

<!DOCTYPE html>

HTML CSS\Head section

Browser Formatting HTMLCode

Set metadata values for interpreting document contents

  • The <head> element is a container for metadata (data about data) and is placed between the <html> tag and the <body> tag
  • Metadata describes how to interpret and format the HTML document stored within the <body> tag

W3Schools Head tag

->

Sample code

<head>
  <title>UrTitle</title>
</head>

HTML CSS\Hide content

Browser Formatting HTMLCode

Hide content until user action

  • CSS style name = display
  • value = none
  • Note: The entire tag and sub-tag structure is hidden
  • Note: To hide the root tag and show a child tag, use CSS styles visibility: hidden and visibility: visible, though the parent markup will still take up screen real estate

StackOverflow Hide Parent Show Child tag

->


HTML CSS\HTTP-EQUIV Document Type

Browser FileSystem HTMLCode

Simulate an HTTP Respsonse header

  • The http-equiv attribute value content-type provides an HTTP header specifying that the character encoding for the document is in the content attribute

W3Schools Meta HTTP-EQUIV

->

Sample code

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />

HTML CSS\iFrame to Local HTML file

Extract FileSystem HTMLCode
<iframe src="UrPath\UrFile.html" scrolling=yes style="border-style:none;height:75%;width:100%" ></iframe>

HTML CSS\Language attribute on tags

Browser Formatting HTMLCode

Allow screen-reader to identify the page's default language and / or accent

  • tag name = any
  • lang attr = an ISO-639 Language code
  • The official W3C recommendation is to declare the primary language for each Web page with a <...lang => attribute in the <html> tag
  • Note: The LANG tag (i.e. the lang="" attribute) is designed to signal screen readers pronunciation engines to switch to another language or accent

PSU.edu LangTag

->

Sample code

<html lang="en-GB">

HTML CSS\META Tag names

AssignVariable Browser HTMLCode

Identify tool or program used to create the website

  • tag name = META
  • name attr = generator
  • content attr = The name of the program you used to create your website
  • Note: This tag is automatically inserted by website-generating applications
  • Note :People who don’t want to advertise which tool or program they used to create the website can remove this tag from the generated pages

MetaTags.org Generator

->

Sample code

<meta name="generator" content="UrProgramTitle" />

Identifies the name of the application running in the web page

  • tag name = META
  • name attr = application-name
  • content attr = The application that is dynamically supplying content for the current web page
  • Note: isolated web pages shouldn't define an application-name

Mozilla.org META tags

->

<meta name="application-name" content="UrApplicationTitle" />

Supply hints about the size of the initial size of the viewport

  • tag name = META
  • name attr = viewport'
  • content attr = comma-separated list of equates
  • Note: This is used by mobile devices only
  • Note: The default values may vary between devices and browsers
  • Note: Disabling zooming capabilities by setting user-scalable to a value of no prevents people experiencing low vision conditions from being able to read and understand page content
  • width = ( A positive integer number ) or ( the text device-width )
  • height = ( A positive integer) or ( the text device-height )
  • initial-scale = A positive number between 0.0 and 10.0
  • maximum-scale = A positive number between 0.0 and 10.0
  • minimum-scale = A positive number between 0.0 and 10.0
  • user-scalable = yes, no
  • viewport-fit = auto', 'contain, cover

Mozilla.org META tags

->

Sample code

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

Include developer or company information in document

  • tag name = meta
  • name attr = copyright, ur_app_name-version
  • content attr = Any text data
  • Note: This information is not used by the browser

HTML CSS\Meta Tag Schema

AssignVariable Browser HTMLCode

W3.org HTML401 Meta

->

This specification does not define a set of legal meta data properties. The meaning of a property and the set of legal values for that property should be defined in a reference lexicon called a profile.

W3.org HTML401 Profiles

->

The profile attribute of the HEAD specifies the location of a meta data profile. The value of the profile attribute is a URI. User agents may use this URI in two ways:

  • As a globally unique name.

User agents may be able to recognize the name (without actually retrieving the profile) and perform some activity based on known conventions for that profile. For instance, search engines could provide an interface for searching through catalogs of HTML documents, where these documents all use the same profile for representing catalog entries.

  • As a link.

User agents may dereference the URI and perform some activity based on the actual definitions within the profile (e.g., authorize the usage of the profile within the current HTML document). This specification does not define formats for profiles.


HTML CSS\Noscript alternate content

EXT

Add content when viewed with JavaScript-disabled browsers

  • tag name = noscript
  • Note: The tag contents are displayed to users that have disabled scripts in their browser or have a browser that doesn't support user action event scripting

W3Schools NoScript tag

->

Sample code

</noscript>
<!--Javascript-disabled browser additional content-->
</noscript>
<!--Ordinary content-->

HTML CSS\Padding and Margin

CSSCode Formatting HTMLCode
style="margin-left:30px"

style="padding-left:10px"

HTML CSS\Table Rows Alternate

CSSCode Formatting HTMLCode

Stylesheet classes:

.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}

HTML using class

<table class="alternating-rows">
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

HTML CSS\Website icon

Browser FileSystem Formatting HTMLCode

Show an icon next to the Website Name

  • tag name = link
  • rel attr = icon, shortcut icon
  • href attr = Website icon filename, relative path, or full path
  • Note: The favicon is loaded as soon as the browsers parses the link rel="icon" declaration, or after the page is loaded when the link is not found
  • Note: The icon keyword may be preceded by the keyword "shortcut". If the "shortcut" keyword is present, the rel attribute's entire value must be an ASCII case-insensitive match for the string "shortcut icon" (with a single U+0020 SPACE character between the tokens and no other ASCII whitespace).

MathiasBynens Rel Icon

->

WHATWg.org Link Icon

->

Sample code

<link rel="shortcut icon" href="favicon.ico">

Instapaper

DOC

  1. Export as CSV
  2. Parse file


Instapaper\Export as CSV

Extract FileSystem Service

[https://www.instapaper.com/u]
- [Top-right icon]
- Click login-name menu, option Settings -> Navigates page
- [Settings page, Export section]
- Click link Download .CSV file -> Opens dialog
- Click button OK -> Starts download, closes dialog

[CSV file]
- Header fields =

URL
Title
Selection
Folder
Timestamp

- Header line =

URL,Title,Selection,Folder,Timestamp

- Sample data 1 =

https://m.youtube.com/watch?v=ABC123DEF&index=14,"""UrQuotedText"" - UrVideoTitle",UrCommentText,"UrInstapaperFolder",1605840648

- Sample data 1 =

https://www.urcompany.com/urfolder/urarticle/,UrArticleTitle,,UrInstapaperFolder,UrCommentText1603883475

Instapaper\Parse file

Extract Service Text
\define link_title()
''[<$list filter="[<http_text>split[,]butlast[]last[]]" />]'' <$list filter="[<http_text>split[,]rest[]first[]]" />
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]floor[]]"><$vars tid_year=<<currentTiddler>> >
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]subtract<tid_year>multiply[12]floor[]]"><$vars tid_month=<<currentTiddler>> >
(<<tid_year>>-<<tid_month>>)
</$vars></$list>
</$vars></$list>
<ul>
<$list filter='[<http_text>split[,]butlast[]butlast[]butfirst[]butfirst[]join[,]split["]butfirst[]butlast[]join["]split[""]join["]split[...]]'>
<li><<currentTiddler>></li>
</$list>
</ul>
\end
<$list filter="[{WebNotes\Data}split[http]count[]]" ><$vars total_count=<<currentTiddler>> >Count of entries: <<total_count>><br><br>
<!--
<$button>
<$action-setfield $tiddler="$:/state/popup/audit_1k" text="0"/>
Reset
</$button><br>

<$button>
<$list filter="[{$:/state/popup/audit_1k}add[1000]]">
<$action-setfield $tiddler="$:/state/popup/audit_1k" text=<<currentTiddler>> />
Next 1k
</$list>
</$button><br>
{{$:/state/popup/audit_1k}}

<$list filter="[{WebNotes\Data}split[http]first{$:/state/popup/audit_1k}last[1000]]"><$vars http_text=<<currentTiddler>> >
-->
<$list filter="[{WebNotes\Data}split[{{]join[-opencurlybrace-]split[http]]"><$vars http_text=<<currentTiddler>> >
<$list filter="[<http_text>split[,]first[]!suffix[URL]addprefix[http]]"><$vars http_link=<<currentTiddler>> >
<$list filter="[all[tiddlers]field:twnote<currentTiddler>count[]match[0]]">
<<http_link>><br>
- <<link_title>> <br>
</$list>
</$vars></$list>
</$vars></$list>
</$vars></$list>

IrfanView

DOC

  1. Contact Sheet


IrfanView\Contact Sheet

Formatting Video WindowsOS

[IrfanView app]
- Open one thumbnail image -> Loads image
- Click the File menu option Thumbnails -> Opens dialog
- [Thumbnails dialog]
- Select all files in the folder
- Click the File menu, option Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size


JavaScript

DOC

  1. Comment text
  2. Execute Nameless Function
  3. Exports object
  4. Invalid Variable Names
  5. Labels
  6. Logical And/Or
  7. Multi-line string
  8. Run in HTML Document
  9. Strict Mode
  10. String Escape Codes
  11. This object
  12. TypeOf Name


JavaScript\Comment text

Browser CSSCode FileSystem

Place a comment text block inside of a JavaScript program

  • tag name = script
  • type attr = text/javascript
  • Start JavaScript comment text block with forward-slash asterisk ( /* )
  • End comment text with asterisk forward-slash ( */ )
  • Start JavaScript comment text line with two forward-slashes ( // )

Sample code

<style type="text/javascript">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>

JavaScript\Execute Nameless Function

FileSystem JavaScriptCode UserAction
;(
    function() {
        alert('hi');
        }
    )();

JavaScript\Exports object

FileSystem JavaScriptCode

Determine if running under Node.JS

  • Initially at least, exports is a reference to module.exports
  • If you assign anything to module.exports, exports is not no longer a reference to it, and exports loses all its power

SitePoint Exports Node.JS

->


JavaScript\Invalid Variable Names

AssignVariable ErrorHandling JavaScriptCode

JavaScript Strict Mode

->

Strict mode makes assignments which would otherwise silently fail to throw an exception. For example, NaN is a non-writable global variable. In normal code assigning to NaN does nothing; the developer receives no failure feedback. In strict mode assigning to NaN throws an exception.

'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError

Strict mode in ECMAScript 2015 forbids setting properties on primitive values. Without strict mode, setting properties is simply ignored (no-op), with strict mode, however, a TypeError is thrown.

(function() {
'use strict';

false.true = '';         // TypeError
(14).sailing = 'home';   // TypeError
'with'.you = 'far away'; // TypeError

})();

JavaScript\Labels

CodeLibrary FileSystem JavaScriptCode

The labeled statement can be used with break or continue statements.

List: 
while(counter < 50)
{
     userInput += userInput;
     counter++;
     if(userInput > 10000)
     {
          break List;
     }
}
var i = 100, j = 100;
outerloop:
while(i>0) {
  while(j>0) {
   j++

   if(j>50) {
     break outerloop;
   }
  }
i++

}
loop1:
for (let i = 0; i < 5; i++) {
  if (i === 1) {
    continue loop1;
  }
  str = str + i;
}

JavaScript\Logical And/Or

JavaScriptCode Numbers

If a value can be converted to true, the value is so-called truthy. If a value can be converted to false, the value is so-called falsy.

Examples of expressions that can be converted to false are:

  • null
  • NaN
  • 0
  • empty string ( "" or '' ) or empty template literal ( `` )
  • undefined

The logical OR expression is evaluated left to right, and first truthy returned expression stops evaluation of the remaining expressions

The && operator is executed before the || operator

Note: If you use this operator to provide a default value to some variable, be aware that any falsy value will not be used. If you only need to filter out null or undefined, consider using the nullish coalescing operator ( ?? )


JavaScript\Multi-line string

Formatting JavaScriptCode Text

It's not a multiline string, it's a one line string split over multiple lines of code that make up a single statement.

Old version uses backslash as a line continuation character:

eval(" \
alert('hi'); \
");

New version uses backtick character as multi-line string:

WARNING: Not supported by IE

eval(`
alert('hi');
`);

Use string concatenation instead:

eval(
"var v1 = 'hi';" +
"alert(v1);"
);

JavaScript\Run in HTML Document

HTMLCode JavaScriptCode UserAction
<html>
  <body><script type = "text/javascript">window.onerror=function(msg,url,line){alert("Line number = "+line+"\nMessage:\n\n"+msg)}</script>
    <script type="text/javascript">
alert('hi';
      </script>
    </body>
  </html>

JavaScript\Strict Mode

CodeLibrary JavaScriptCode Text

Show strict mode compilation errors on specific scripts or functions

  • First statement in script or function: 'use strict'; or "use strict";
  • Note: Strict mode applies to entire scripts or to individual functions, not individual block statements enclosed in {} braces within a function
  • Note: Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally
  • Note: The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it

MozillaDeveloper Strict mode

->

Sample data

"use strict";
mistypeVariable = 17;

Result in Developer Tools, Javascript Console:

Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLineNumber
<script type="module">
mistypeVariable = 17;
</script>

Result:

Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLine

JavaScript\String Escape Codes

CodeLibrary JavaScriptCode Text

Here are all the string escape codes:

\0 The NUL character (\u0000)
\b Backspace (\u0008)
\t Horizontal tab (\u0009)
\n Newline (\u000A)
\v Vertical tab (\u000B)
\f Form feed (\u000C)
\r Carriage return (\u000D)
\" Double quote (\u0022)
\' Apostrophe or single quote (\u0027)
\\ Backslash (\u005C)
\x XX The Latin-1 character specified by the two hexadecimal digits XX
\u XXXX The Unicode character specified by the four hexadecimal digits XXXX


JavaScript\This object

CodeLibrary JavaScriptCode

JavaScript This Parameter

->

Functions called via property references get "this" set for them: This is the part that really makes it seem like JavaScript has methods: The "this" reference gets set automagically to the object instance if you call a function via a property reference.

Within that call, use the object in question as "this". Getting the function reference from an object property doesn't link it in any way to the object the property came from. The JavaScript engine treats calls of functions just retrieved from object properties as special and sets up "this" accordingly. Essentially, "this" is just a function argument that's passed into the function as an implicit feature of calling a function via a property reference.

JavaScript gives us the call and apply methods on function instances, with which we can say explicitly what we want "this" to be. If you say myfunction.call(myobject), you're saying "call myfunction and use myobject as 'this'", which is what the property-retrieval stuff does implicitly for you.

UrObject.UrFunction();

- equates to -

UrObject.UrFunction.call(UrObject);

Everything can be seen as a function.

window['UrObject']['UrFunction'].call(window['UrObject']);

Getting the function reference from the property (UrObject.UrFunction) is distinct from the fact we're calling it (call) is distinct from what "this" should be ((UrObject)).

JavaScript Closures

->

The interpreter creates a call object for this particular execution of the function and sets some properties on that call object before passing it into the function's code.

  • A property called arguments which is an array (of sorts, in most implementations it's not actually an Array object) of the actual arguments we called the function with, plus a callee property which is a reference to the function being called.
  • A property for each of the arguments defined by the function declaration. The values of these properties are set to the values passed into the function. If any arguments weren't specified (because JavaScript lets you call functions with however many arguments you want, regardless of the definition), properties for any missing arguments are still created on the call object — with the value undefined.
  • A property for every declared variable within the function (e.g., every "var" statement). (These start out with the value undefined.)
window.UrFunction(UrObject1, UrObject2);

That creates a call object for this execution of updateDisplay that essentially looks like this:

call.arguments = [UrObject1, UrObject2]
call.arguments.callee = UrFunction
call.ur_input_parm1 = UrObject1
call.ur_input_parm2 = UrObject2
call.internal_var1 = undefined

The use of the call object is implicit, because once the call object is created, it's put at the top of the scope chain for the duration of the function call.


JavaScript\TypeOf Name

CodeLibrary JavaScriptCode Text

Get string representing object type

  • typeof always returns a string
  • Note: typeof operator takes precedence over string concatenation ( + )
  • Note: type a let or const variable in a block before they are declared will throw a ReferenceError
  • Undefined, undeclared variable, or unassigned variable = "undefined"
  • Boolean(1), !!(1) = "boolean"
  • Number('321') , Infinity, NaN = "number"
  • Bigint, 321n = "bigint"
  • String = "string"
  • Symbol = "symbol"
  • Function() {}, class UrClassName {}, = "function"
  • null, object, {ur_prop_name: ur_prop_value}, [ur_val1, ur_val2, ur_val3], new Date(), /regex/ = "object"

JavaScriptBookmarklets

DOC

  1. Bibliographic citation
  2. Clear all CSS
  3. Convert to Inline CSS
  4. Edit current page
  5. Extract iFrame pages
  6. Extract images
  7. Extract plain text
  8. Unescape HTML code
  9. View HTML Source
  10. View HTML to TW


JavaScriptBookmarklets\Extract iFrame pages

Extract FileSystem HTMLCode JavaScriptCode
(function(){ var imgs = document.getElementsByTagName('iframe'),t=[]; for (var i=0, n=imgs.length;i'+ imgs[i].src+''); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract images

Extract FileSystem HTMLCode JavaScriptCode
avascript:(function(){ var imgs = document.getElementsByTagName('img'),t=[]; for (var i=0, n=imgs.length;i<n;i++) t.push('<a href="'+imgs[i].src+'"><img src="'+ imgs[i].src+'" width="100"></a>'); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract plain text

Extract JavaScriptCode Text

Copy the HTML body to a new window, so CSS and Javascript are ignored

avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML;void(newWindow.focus());}

Copy the HTML body to a new window showing the HTML tags, so you can see the HTML code

avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/&/g,"&amp;").replace(/</g,"<br>&lt;");void(newWindow.focus());}

Copy the HTML body without any HTML tags, so the text is loaded without any HTML or CSS styling

avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/<[^>]+>/g, '<br>');void(newWindow.focus());}

keyboard action FontLarge

$:/positivesigner/text-ref $:/tags/KeyboardShortcut


keyboard action FontNormal

$:/positivesigner/text-ref $:/tags/KeyboardShortcut


keyboard action HomeTiddlers

$:/positivesigner/home-button $:/tags/KeyboardShortcut

keyboard action SaveAllChanges

$:/positivesigner/base-install $:/tags/KeyboardShortcut


mcr glbl_article_list

$:/positivesigner/text-ref $:/tags/Macro

mcr glbl_code_split

$:/positivesigner/text-ref $:/tags/Macro

mcr glbl_compare_lines

$:/positivesigner/text-ref $:/tags/Macro

mcr glbl_dt_ddd

$:/positivesigner/text-ref $:/tags/Macro

mcr glbl_ext

$:/positivesigner/text-ref $:/tags/Macro

MicrosoftRemoteDesktop

DOC

  1. Setup PC


MicrosoftRemoteDesktop\Setup PC

AndroidOS UserAction WindowsOS

Microsoft RemoteDesktop Enable

->


Panel

$:/positivesigner/text-ref
  • If there is an existing personal access token,
  • Click on the name -> Navigates page
  • Click button Regenerate Token -> Navigates page
  • Click button Copy to Clipboard
  • Otherwise create a new token
  • Note = name of end user and device
  • Must be unique
  • Each device should get a different token
  • checkbox "repo" = set
  • Click button Generate token -> Navigates page
  • Click button Copy to Clipboard

  • [Saving tab, GitHub Saver sub-tab]
  • Paste into field "Password, OAUTH token, or personal access token"
  • Close the Control Panel card

  • Click button
  • Wait a few seconds for the "Saved wiki" notification
  • The token is saved in internal browser storage
  • If you get a "401" error, go back to step 1 to generate a new token

Recent Entries

$:/positivesigner/text-ref

Search All Fields

Tags Count Audit

View All Cards

View All Code

Font Size


Regular Expressions

DOC

  1. Explanation


Regular Expressions\Explanation

CodeLibrary RegExCode

TiddlyWiki\Regular Expression

Regexp Filter with brackets

->

The code would get complexer [sic] too as "[[...]]" can't be put directly in the regex in TW. You'd have to do it through a variable. And since "[character class]" is reserved in regex you'd also have to escape square brackets "[\[\]]".

Regular Expression Quantifiers

->

Regular expressions take a string of text, and returns a YES or NO as to whether it matches a character pattern.

You can specify a literal character.

  • A letter or series of letters
    • ABC matches B? -,/ABC\,- ABC split out B? -,/A\,- -,/C\,-
  • \. is a literal period, because without the \ escape it would have special meaning
    • AA.AA matches \.? -,/AA.AA\,- AA.AA split out \.? -,/AA\,- -,/AA\,-

You can use tokens to specify a kind of character to match.

  • \d is a numeric digit 0 through 9
    • A2C matches \d? -,/A2C\,- A2C split out \d? -,/A\,- -,/C\,-
  • \D is any non-numeric digit
    • 5A8 matches \D? -,/5A8\,- 5A8 split out \D? -,/5\,- -,/8\,-
  • \s is a whitespace character; like space, tab, or line feed
    • A C matches \s? -,/A C\,- A C split out \s? -,/A\,- -,/C\,-
  • \S is a non-whitespace character
    • A matches \S? -,/A\,- A split out \S? -,/\,- -,/\,-
  • \W is a whitespace or punctuation character (non-word character)
    • ; matches \W? -,/;\,- ; split out \W? -,/\,- -,/\,-
  • \w is a word character (non-whitespace and non-punctuation character)
    • A matches \w? -,/A\,- A split out \w? -,/\,- -,/\,-
  • . period is any character
    • A matches .? -,/A\,- A split out .? -,/\,- -,/\,-

You can get out of having to use the \ escape over a block of text if you prefer to type it out.

  • \QOne. Two. Three.\E treats anything between the delimiters as a literal string, like "One. Two. Three."
    • Useful to escape metacharacters
    • Otherwise the periods would be special characters applied to the one letter before each period
    • You can also write it as One\. Two\. Three\.

A regex quantifier such as + tells the regex engine to match a certain quantity of the character, token or subexpression immediately to its left.

  • A+ the quantifier + applies to A
    • AAABCCC matches B+? -,/AAABCCC\,- AAABCCC split out B+? -,/AAA\,- -,/CCC\,-
    • AAABBBCCC matches B+? -,/AAABBBCCC\,- AAABBBCCC split out B+? -,/AAA\,- -,/CCC\,-
  • A* the quantifier * applies to A
    • ABBBC matches B*? -,/ABBBC\,- ABBBC split out B*? -,/A\,- -,/C\,-
    • AC matches B*? -,/AC\,- AC split out B*? -,/A\,- -,/C\,-
  • ABC? the quantifier ? applies to the C—not to ABC
    • ABCD matches BC?? -,/ABCD\,- ABCD split out BC?? -,/A\,- -,/D\,-
    • ABD matches BC?? -,/ABD\,- ABD split out BC?? -,/A\,- -,/D\,-
  • (?:A|B|C)+ the quantifier + applies to the subexpression
    • ABCD matches (?:B|C)+? -,/ABCD\,- ABCD split out (?:B|C)+? -,/A\,- -,/D\,-
    • ABD matches (?:B|C)+? -,/ABD\,- ABD split out (?:B|C)+? -,/A\,- -,/D\,-
  • \QA.B.C\E+ is treated as a sequence of literals, so the quantifier only applies to the last character
    • This could also be written as A\.B\.C+

By default, a quantifier tells the engine to match as many instances of its quantified token or subpattern as possible. This behavior is called greedy.

  • A+ is greedy, and matches all the number characters in a row from the starting point where exists (a number)
    • ABBBCD matches B+? -,/ABBBCD\,- ABBBCD split out B+? -,/A\,- -,/CD\,-
  • A+B is greedy, and matches all the number characters in a row where exists (a letter B after a letter A)
    • ABBBCD matches B+C? -,/ABBBCD\,- ABBBCD split out B+C? -,/A\,- -,/D\,-
    • ABBBCD matches (B+)C? -,/ABBBCD\,- ABBBCD split out (B+)C? -,/A\,- -,/BBB\,- -,/D\,-

In contrast to the standard greedy quantifier, which eats up as many instances of the quantified token as possible, a lazy (sometimes called reluctant) quantifier tells the engine to match as few of the quantified tokens as needed.

  • \w*?B is lazy, and matches as few word characters in a row as needed where exists (a letter B after a word character)
    • +ABCCC+ matches \w*?C? -,/+ABCCC+\,- +ABCCC+ split out \w*?C? -,/+\,- -,/\,- -,/\,- -,/+\,-
    • +ABCCC+ matches \w*C? -,/+ABCCC+\,- +ABCCC+ split out \w*C? -,/+\,- -,/+\,-

In contrast to the standard docile quantifier, which gives up characters if needed in order to allow the rest of the pattern to match, a possessive quantifier tells the engine that even if what follows in the pattern fails to match, it will hang on to its characters.

  • A++ is possessive—it matches as many characters as needed and never gives any of them back.
    • Whereas the regex A+. matches the string AAA, A++. doesn't. At first, the token A++ greedily matches all the A characters in the string. The engine then advances to the next token in the pattern. The dot . fails to match because there are no characters left to match. The engine looks if there is something to backtrack. But A++ is possessive, so it will not give up any characters. There is nothing to backtrack, and the pattern fails. In contrast, with A+., the A+ would have given up the final A, allowing the dot to match.

You can specify a number range of characters to repeat.

  • A{2,9} uses two to nine As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
    • +ABCCC+ matches C{1,2}? -,/+ABCCC+\,- +ABCCC+ split out C{1,2}? -,/+AB\,- -,/\,- -,/+\,-
    • +ABCCC+ matches C{2,2}? -,/+ABCCC+\,- +ABCCC+ split out C{2,2}? -,/+AB\,- -,/C+\,-
    • +ABCCC+ matches C{2,9}? -,/+ABCCC+\,- +ABCCC+ split out C{2,9}? -,/+AB\,- -,/+\,-
  • A{2,} uses two or more As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
    • +ABCCC+ matches C{2,}? -,/+ABCCC+\,- +ABCCC+ split out C{2,}? -,/+AB\,- -,/+\,-

You can use negated character classs to match characters other up to the one you want.

  • ^[^\.]* skips up to first period
    • AB.C.D matches ^[^\.]*? -,/AB.C.D\,- AB.C.D split out ^[^\.]*? -,/\,- -,/.C.D\,-
  • ^.*\. skips up to last period
    • AB.C.D matches ^.*\.? -,/AB.C.D\,- AB.C.D split out ^.*\.? -,/\,- -,/D\,-

Tempered Greedy Token Solution

  • A(?:(?!B).)*B stops at the first B instead of the last B
    • AB.C.DCE matches B(?:(?!C).)*C? -,/AB.C.DCE\,- AB.C.DCE split out B(?:(?!C).)*C? -,/A\,- -,/.DCE\,-
    • AB.C.DCE matches B.*C? -,/AB.C.DCE\,- AB.C.DCE split out B.*C? -,/A\,- -,/E\,-
  • A(?:(?!C)(?!B).)*B stops at the first B unless there is a C between the A and B
    • AB.CA matches B(?:(?!D)(?!C).)*C? -,/AB.CA\,- AB.CA split out B(?:(?!D)(?!C).)*C? -,/A\,- -,/A\,-
    • AB.CAB.FGHBC matches B(?:(?!D)(?!C).)*C? -,/AB.CAB.FGHBC\,- AB.CAB.FGHBC split out B(?:(?!D)(?!C).)*C? -,/A\,- -,/A\,- -,/\,-
    • AB.CAB.DFGHBC matches B(?:(?!D)(?!C).)*C? -,/AB.CAB.DFGHBC\,- AB.CAB.DFGHBC split out B(?:(?!D)(?!C).)*C? -,/A\,- -,/AB.DFGH\,- -,/\,-

Search All Fields

$:/positivesigner/text-ref




SQLite

DOC

  1. Blob text
  2. Database Browser
  3. Information Schema
  4. String Manipulation
  5. Top or Limit records


SQLite\Blob text

AssignVariable Filter SQLCode

SQLite Blob text

->

WITH RECURSIVE test(c,cur) as (
     SELECT '', HEX(blob_field) FROM UrTable WHERE UrPK = 6
   UNION ALL
    select c || char((case substr(cur,1,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,1,1) end)*16
               + (case substr(cur,2,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,2,1) end)),
substr(cur,3)
from test where length(cur)>0
)
select * from test

SQLite\Database Browser

Extract FileSystem SQLCode WindowsOS

SQLite DB Browser

->

I used DB Browser for SQLite - .zip (no installer) for 64-bit Windows


SQLite\Information Schema

Extract FileSystem SQLCode

SQLite schema information

->

SELECT name, sql FROM sqlite_master
WHERE type='table'
ORDER BY name;

SQLite Language functions

->

sqlite_source_id()

--version string of SQLite Library source code
2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f

sqlite_version()

--version string of SQLite Library running
3.33.0

SQLite\String Manipulation

Extract SQLCode Text

SQLite Language functions

->

--comment

CHAR(unicode_char_list)

COALESCE(field_list)

HEX(field)

IFNULL(field, default_text)

INSTR(field, search_text)

LENGTH(field)

LIKE(field, comparison_text)

  • field LIKE comparisontext
  • LIKE(field, comparison_text, escape_char)

LOWER(field)

LTRIM(field)

  • LTRIM(field, chars_to_remove)

PRINTF(format_text, field_list)

REPLACE(field, search_text, new_text)

RTRIM(field)

  • RTRIM(field, chars_to_remove)

SUBSTR(field, start_char)

  • SUBSTR(field, start_char, char_count)

TRIM(field)

  • TRIM(field, chars_to_remove)

typeof(field)

  • "null", "integer", "real", "text", or "blob".

UNICODE(number)

UPPER(field)


SQLite\Top or Limit records

Filter Numbers SQLCode

SQLite Top 5 Records

->

SELECT * FROM Table_Name LIMIT 5;


Tags Count Audit

$:/positivesigner/text-ref

JavaScriptBookmarklets\Bibliographic citation

JavaScriptBookmarklets\Clear all CSS

JavaScriptBookmarklets\Convert to Inline CSS

JavaScriptBookmarklets\Edit current page

JavaScriptBookmarklets\Unescape HTML code

JavaScriptBookmarklets\View HTML Source

JavaScriptBookmarklets\View HTML to TW

VBNetCode\Unicode Code Point

VBNetCode\Version


btn Delete Cards

DivPop.svg

ext TW Return

Font Size

Panel

Recent Entries

Search All Fields

Tags Count Audit

View All Cards

View All Code


template ExportAllCode

$:/positivesigner/base-install $:/tags/Exporter


$:/config/MissingLinks

no

$:/config/Navigation/openLinkFromOutsideRiver

bottom

$:/config/Navigation/Permalinkview/CopyToClipboard

no

$:/config/ShortcutInfo/font-large


$:/config/ShortcutInfo/font-normal


$:/config/ShortcutInfo/home-tiddlers


$:/config/ShortcutInfo/save-all-changes


$:/config/shortcuts/font-large

ctrl-shift-Quote

$:/config/shortcuts/font-normal

ctrl-shift-Comma

$:/config/shortcuts/home-tiddlers

alt-H

$:/config/shortcuts/save-all-changes

alt-S

$:/config/TextEditor/EnableToolbar

no

$:/config/ViewToolbarButtons/Visibility/$:/positivesigner/gcmpr/btn gcmpr card

hide

$:/config/WikiParserRules/Inline/wikilink

disable

$:/DefaultTiddlers

[tag[INDEX]has[sort_ord]sort[title]]
[tag[INDEX]!has[sort_ord]sort[title]]

$:/language/DefaultNewTiddlerTitle

New Card

$:/positivesigner/base-install

\define show_pill()
<<tag-pill tag:"$(cur_entry)$" >>
\end
---
<$list variable=cur_entry filter="[prefix[$:/positivesigner/]is[tag]sort[]]">

<<cur_entry>>
</$list>

$:/positivesigner/div-pop


$:/positivesigner/gcmpr


$:/positivesigner/gcmpr/btn gcmpr card

<<gcmpr_btn_cmp_current>> 

$:/positivesigner/gcmpr/mcr gcmpr_compare_card

\define gcmpr_compare_card(ur_ttb_card)
<$list variable=ttb_card filter="[[$ur_ttb_card$]!match[]]">
<$list variable=compare_card filter="[<ttb_card>addprefix[$:/state/popup/compare-card/]]">
<$link to=<<ttb_card>> />
<<gcmpr_ref_edit_source_text>>
<<gcmpr_ref_copy_over_ttb_card>>
<br>
<$link to=<<compare_card>> />
<<gcmpr_ref_replace_comment_endings>>
<<gcmpr_ref_disp_diff_text>>
<$edit-text autoHeight=no tiddler=<<compare_card>> tag=textarea default="" />
<<gcmpr_ref_disp_textedit_link>>
</$list><!--compare_card-->
</$list><!--ttb_card-->
<!--gcmpr_compare_card-->
\end

\define gcmpr_ref_edit_source_text(ttb_card, compare_card)
<$vars enr_text="text" >
<$list variable=source_text filter="[<ttb_card>get<enr_text>else[]]">
<$button>
<$action-setfield $tiddler=<<compare_card>> text=<<source_text>> />
Copy Source
</$button>
</$list><!--source_text-->
</$vars><!--enr_text-->
<!--gcmpr_ref_edit_source_text-->
\end

\define gcmpr_ref_copy_over_ttb_card(ttb_card, compare_card)
<$vars enr_text="text" >
<$list variable=compare_text filter="[<compare_card>get<enr_text>else[]]">
<$button>
<$action-setfield $tiddler=<<ttb_card>> text=<<compare_text>> />
Overwrite Source
</$button>
</$list><!--compare_text-->
</$vars><!--enr_text-->
<!--gcmpr_ref_copy_over_ttb_card-->
\end

\define gcmpr_ref_replace_comment_endings(ttb_card, compare_card)
<$button>
<$vars comment_flag="--" lit_exclm="!" lit_lt="<" lit_gt=">" enr_text="text" >
<$wikify name=lit_lf text="&#10;">
<$list variable=comment_open_text filter="[<lit_lt>addsuffix<lit_exclm>addsuffix<comment_flag>]">
<$list variable=comment_close_text filter="[<comment_flag>addsuffix<lit_gt>]">
<$list variable=comment_close_replace filter="[<comment_flag>addsuffix<lit_exclm>addsuffix<lit_gt>]">
<$list variable=replace_text filter="[<compare_card>get<enr_text>split<comment_close_text>join<comment_close_replace>addprefix<lit_lf>addprefix<comment_open_text>addsuffix<lit_lf>addsuffix<comment_close_text>]">
<$action-setfield $tiddler=<<compare_card>> text=<<replace_text>> />
</$list><!--replace_text-->
</$list><!--comment_close_replace-->
</$list><!--comment_close_text-->
</$list><!--comment_open_text-->
</$wikify>
</$vars><!--comment_flag, lit_exclm, lit_lt, lit_gt-->
Replace comment endings
</$button><br>
<!--gcmpr_ref_replace_comment_endings-->
\end

\define gcmpr_ref_disp_diff_text()
<$list variable=val_ttb_card filter="[<ttb_card>get[text]!match[]]">
<$list variable=val_compare_card filter="[<compare_card>get[text]!match[]]">
<$diff-text source=<<val_ttb_card>> dest=<<val_compare_card>> />
</$list><!--val_compare_card-->
</$list><!--val_ttb_card-->
<!--gcmpr_ref_disp_diff_text-->
\end

\define gcmpr_ref_disp_textedit_link()
<$list variable=cur_url filter="[{$:/info/url/full}]">
<$list variable=new_link filter="[<cur_url>addsuffix[#]addsuffix[$:/positivesigner/gcmpr/textarea]split[$:]join[%24%3A]]">
<a href=<<new_link>> target="_blank" >text editor</a>
</$list>
</$list>
<!--gcmpr_ref_disp_textedit_link-->
\end

\define gcmpr_btn_cmp_current()
<$list variable=cur_card filter="[all[current]]">
<$list variable=dest_card filter="[<cur_card>addprefix[$:/state/popup/gcmpr/]]">
<$vars lit_lt="<" lit_gt=">" lit_s=" " lit_qs='"' macro_name="gcmpr_compare_card" enr_text="text" >
<$list variable=macro_call_text filter="[<lit_lt>addsuffix<lit_lt>addsuffix<macro_name>addsuffix<lit_s>addsuffix<lit_qs>addsuffix<cur_card>addsuffix<lit_qs>addsuffix<lit_gt>addsuffix<lit_gt>]">
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler=<<dest_card>> text=<<macro_call_text>> />
<$action-navigate $to=<<dest_card>> />
Compare to Textbox
</$button>
</$list><!--macro_call_text-->
</$vars><!--lit_lt-->
</$list><!--dest_card-->
</$list><!--cur_card-->
<!--gcmpr_btn_cmp_current-->
\end

\define gcmpr_textarea_new()
<$vars enr_text="text" enr_new_filename="new_filename" enr_rows="rows" enr_cols="cols" enr_disp_btn_incr_decr="disp_btn_incr_decr" lit_state_popup_prefix="$:/state/popup/gcmpr_textarea/" lit_default_rows="20" lit_default_cols="160" cur_card=<<currentTiddler>> >
<$list variable=temp_card filter="[<cur_card>addprefix<lit_state_popup_prefix>]">
New file name:
@@margin-left:5px;
<$edit-text tiddler=<<temp_card>> field=new_filename placeholder="" autoHeight=yes tag=input/>
@@
<$list variable=val_disp_btn_incr_decr filter="[<temp_card>get<enr_disp_btn_incr_decr>!match[]else[]]">
<$list variable=val_rows filter="[<temp_card>get<enr_rows>!match[]!match[0]else<lit_default_rows>]">
<$list variable=val_cols filter="[<temp_card>get<enr_cols>!match[]!match[0]else<lit_default_cols>]">
<$list variable=val_new_filename filter="[<temp_card>get<enr_new_filename>!match[]]">
<$list variable=new_card filter="[<val_new_filename>addprefix<lit_state_popup_prefix>]">
<$list variable=new_temp_card filter="[<new_card>addprefix<lit_state_popup_prefix>]">
<$list variable=filter_newcard_not_exists filter="[<new_card>!is[tiddler]]">
<$button>
<$list variable=cur_card_text filter="[<cur_card>get<enr_text>]">
<$action-setfield $tiddler=<<new_card>> $field=<<enr_text>> $value=<<cur_card_text>> />
</$list><!--cur_card_text-->
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_new_filename>> $value=<<val_new_filename>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_rows>> $value=<<val_rows>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_cols>> $value=<<val_cols>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_disp_btn_incr_decr>> $value=<<val_disp_btn_incr_decr>> />
<$action-navigate $to=<<new_card>> />
New card
</$button>
</$list><!--filter_newcard_not_exists-->
</$list><!--new_temp_card-->
</$list><!--new_card-->
</$list><!--val_new_filename-->

<br>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>!match[]]">
@@margin-right:20px;
<$button>
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_disp_btn_incr_decr>> $value="" />
Show Resize buttons
</$button>
@@
</$list><!--filter_disp_buttons-->
Rows: <<val_rows>>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>match[]]">
<$button>
<$list variable=val_new_rows filter="[<val_rows>add[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_rows>> $value=<<val_new_rows>> 
/>
</$list><!--val_new_rows-->
+
</$button>
<$list variable=filter_zero_rows filter="[<val_rows>!match[0]]">
<$button>
<$list variable=val_new_rows filter="[<val_rows>subtract[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_rows>> $value=<<val_new_rows>> />
</$list><!--val_new_rows-->
-
</$button>
</$list><!--filter_zero_rows-->
</$list><!--filter_disp_buttons-->
Cols: <<val_cols>>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>match[]]">
<$button>
<$list variable=val_new_cols filter="[<val_cols>add[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_cols>> $value=<<val_new_cols>> />
</$list><!--val_new_cols-->
+
</$button>
<$list variable=filter_zero_cols filter="[<val_cols>!match[0]]">
<$button>
<$list variable=val_new_cols filter="[<val_cols>subtract[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_cols>> $value=<<val_new_cols>> />
</$list><!--val_new_cols-->
-
</$button>
@@margin-left:20px;
<$button>
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_disp_btn_incr_decr>> $value="hide" />
Hide resize buttons
</$button>
@@
</$list><!--filter_disp_buttons-->
</$list><!--filter_zero_cols-->
<br>
<textarea rows=<<val_rows>> cols=<<val_cols>> />
</$list><!--val_cols-->
</$list><!--val_rows-->
</$list><!--val_disp_btn_incr_decr-->
</$list><!--temp_card-->
</$vars><!--enr_new_filename-->
\end

\define glbl_chk(ur_field)
<br><$checkbox tiddler=<<currentTiddler>> field="$ur_field$" unchecked="no" checked="yes"></$checkbox><span style="margin-right:5px;" />
\end

$:/positivesigner/gcmpr/textarea

<<gcmpr_textarea_new>>

$:/positivesigner/home-button


$:/positivesigner/text-ref


$:/themes/tiddlywiki/vanilla/options/sidebarlayout

fluid-fixed

AndroidChromeBrowser

<<glbl_article_list>>

AndroidChromeBrowser\Desktop Shortcut to Website

"""
This does not work for file:///sdcard HTML files
Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Google Chrome app]
- [Non-incognito mode]
- Navigate to website page
- Note: This does not work for file:///sdcard HTML files
- [Top-right icons]
- Click the three-lines menu, option Add to Home screen -> Opens dialog
- [Add to Home screen dialog]
- Shortcut name / UrShortcutName
- Click button Add -> Closes dialog

[Desktop icons]
- Click icon UrShortcutName -> Opens browser

AndroidGit

<<glbl_article_list>>

AndroidGit\Pocket Git pull repository updates

"""
[Pocket Git app]
- [Repositories List page, Top-right icons]
- Click button Preferences (looks like three lines) -Navigates page
- [Preferences page, Defaults section]
- Click link Default Directory -> Opens dialog
- [Select Folder dialog]
- Select the Downloads folder -> Closes dialog
- [Preferences page, Defaults section]
- Note: Default Directory = /storage/emulated/0/Download
- Click button Back (looks like a left arrow) -> Navigates page

- [Repositories List page, Bottom-right icons]
- Click button Create Project (looks like a red button with a Plus sign) -> Opens dialog
- [Create Project dialog]
- Project Name = UrProjectName
- Clone URL = UrRepositoryURL
- Note: Local Path automatically creates a sub-directory under the Downloads folder
- Click the Authentication drop-list, option Password
- Username = UrRepositoryUsername
- Password = UrRepositoryPassword
- [Create Project dialog, Top-right icons]
- Click button Save (looks like a floppy disk) -> Closes dialog

- [Repositories List page]
- Click repository UrProjectName -> Navigates page

- [Repository page, Top-right icons]
- Click the Remotes menu (looks like a cloud), click option Fetch -> Starts process
- Wait for popup message "Finished fetching"
- Click the Remotes menu, click option Pull -> Starts process
- Wait for popup message "Finished pulling"

[File system]
- [Downloads folder]
- Note: All the files in the repository are available under the UrProjectName sub-folder in the Downloads folder

AndroidMultipleUsers

<<glbl_article_list>>

AndroidMultipleUsers\Common access files

"""
When you change users on an Android device, the file:///sdcard/ folder is aliased to a different location for each. There is a specific sub-folder that is aliased to the same location for all users.

[File Manager]
- Navigate to /sdcard/Android/obb
- Create a folder and copy files into it

[Android Notices menu]
- Change the current user

[File Manager]
- Navigate to /sdcard/Android/obb
- You can see the same folder and files from the other login

AndroidProgramming

<<glbl_article_list>>

AndroidProgramming\DCoder

Note: I found that the DCoder app actually submitted the VB code to a web server. So there was no way for me to access the local file system.

```
  'Visual Basic.Net Compiler version 0.0.0.5943 (Mono 4.0.1)

Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Namespace Dcoder
  Public Module Program
    Public Sub Main(args() As string)
      Dim strRET = "Hi"
      For Each strENTRY As String In SubDir_List("/")
          For Each strE2 As String In SubDir_List("/" & strENTRY)
          For Each strE3 As String In SubDir_List("/" & strENTRY)
              strRET &= vbLf & strENTRY & "/" & strE2 & "/" & strE3
          Next strE3
          Next strE2
      Next strENTRY
      
      strRET &= vbLf & "Done"
      Console.WriteLine(strRET)
    End Sub 'Main

    Public Function t1(ur_root_dir As String) As String
        Return "no"
    End Function

    Public Function SubDir_List(ur_root_dir As String) As System.Collections.Generic.List(Of String)
      Dim lstRET = New System.Collections.Generic.List(Of String)
      SubDir_List = lstRET
      Try
      Dim proc = New System.Diagnostics.Process
      Dim stg = new System.Diagnostics.ProcessStartInfo
      proc.StartInfo = stg
      stg.FileName = "ls"
      stg.Arguments = ur_root_dir

      'stg.FileName = "find"
      'stg.Arguments = ". -name '*' -print"

      stg.UseShellExecute = false
      stg.RedirectStandardOutput= true
      stg.RedirectStandardError = true
      stg.CreateNoWindow = true
      proc.Start()
      Dim strCL_OUT = proc.StandardOutput.ReadToEnd()
      'strRET = "[Output: " & vbLf & strCL_OUT & "]"
      'strRET &= vbLf & "(err: " & vbLf & proc.StandardError.ReadToEnd() & ")"
      For Each strENTRY As String In strCL_OUT.Split(CHR(10))
          If strENTRY <> "" Then
              lstRET.Add(strENTRY)
          End If
      Next strENTRY
      Catch ex As System.Exception
      End Try
    End Function 'SubDir_List
  End Module
End Namespace

AndroidQLua

<<glbl_article_list>>

AndroidQLua\Console Commands

"""
[QLua app]
- Click button Console -> Navigates page

- [console window]
- Note: The right-arrow symbol (greater-than sign) is the Lua prompt
- Note: Comment line-endings in a Lua file are separated by two hyhpens
"""

```
--Single-line comment
ur_object.ur_function() --Comment until end of line
```

"""
- Note: Multi-line comments in a Lua file are separated by two hyphens and two open brackets, and closed by two hyphens and two close brackets
"""

```
--[[
Block comment
multiple lines
--]]
```

"""
- Note: Commands in Lua are case sensitive
- - You can create functions named `abc`, `Abc`, `abC`, and `ABC`, and each one can store to a different value

- Note: Exiting the Lua interpreter returns to the Linux Shell command line interpreter that was created by QLua
- Run the `os.exit()` command
"""

```
os.exit()
```

"""
[Linux Shell CLI]
- Note: The $ symbol (dollar sign) is the Linux Shell prompt
- Note: Commands in Linux Shell are case sensitive
- - You can create programs named `abc`, `Abc`, `abC`, and `ABC`, and each one can run different code
- - Most standard Linux Shell commands are named with all lowercase characters, so only `abc` would be the standard way to name a program

- Note: Exiting the Linux Shell returns to the QLua app main page
- Run the `exit` command
"""

```
exit
```


AndroidQLua\Console Run a Program

"""
[Lua console]
- Note: I had problems using the `LoadString` function with the `loadfile` command
- - In the Lua code, replace any references to the `LoadString` function with the `Load` function
- - The `Load` command did not need extra escaping like`\\r` for the parameter, so replace `\\r` with `\r` when using the `Load` command
- Save the result of the loadfile command to create a new function from the file
"""

```
urfile_fn=loadfile('/sdcard/qlua5/ur_file.lua')
```

"""
- Note: This added a row to the _G table
- Note: Just typing a function name or a table name shows the type of data stored in the row
"""

```
_G.urfile
```

"""
- Output is `function: 0x#####`
- Note: any command except _G is an implied name lookup in the _G table
"""

```
urfile
```

"""
- Output is also the same `function: 0x####`
- Note: You can run a function by adding parentheses to the end of the function name
- Running a function can load additional functions into the _G table
"""

```
urfile()
```

"""
- Output is the Lua program output
- Note: Any functions or tables added to the _G table are available
- Note: You can load a Lua function and run it on the same line instead of storing the program in a variable by adding an extra pair of parentheses
"""

```
loadfile('/sdcard/qlua5/ur_file.lua')()
```

"""
- Output is the Lua program output

AndroidQLua\Deploy a Program Module

"""
Note: The `share/5.3` directory under the QLua5 folder is where Lua looks to load "program modules" that must be loaded to the _G array as a prerequisites to running the current program

[QLua Editor]
- Note: I had problems using the `LoadString` function with the `require` command
- - In the Lua code, replace any references to the `Load` function with the `LoadString` function
- - The `LoadString` command needs extra escaping like`\\r` for the parameter, so replace `\r` with `\\r` when using the `LoadString` command

- [Bottom bar]
- Click button Save-As (Looks like a page with a Plus in the bottom-right corner) -> Open dialog

- [Save As dialog]
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = `share`
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder `share`
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = `5.3`
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder `5.3`
- [Bottom bar]
- File name = UrFileName.lua
- Click button OK (looks like a checkmark)

[File Manager]
- Note: Your Lua program is stored in folder `/sdcard/qlua/share/5.3`

[Lua console]
- Note: The require command to loads and runs a program module
- - Do not include the path or the `.lua` file extension
"""

```
require 'UrFileName'
```

"""
- Output is the Lua program output

AndroidQLua\Editor Run a Program

"""
[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icon]
- Click button Open file (looks like a Tabbed folder) -> Opens dialog
- Select file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Note: You can change the source code and save again before each run

- [Bottom bar icons]
- Click button Run (looks like a right-arrow play button) -> Navigates page

- [console window]
- Note: The top line shows the current path and the Linux shell command used to show the editor
- Note: The output of your program is below the first line
- Note: The the last line says "Press enter to exit"

AndroidQLua\MxClasses Design

"""
I created some default functions that I need to see the key/value pairs in Lua tables

[def.lua]
- [def_tcompile]
- This creates a 'tcompile' function that concatenates a table's string values then loads the result as a new function
- [def_ti]
- This creates a 'ti' function that adds a new numbered row to a table
- [def_tia]
- This clears out a global table variable and creates a 'tia' function that calls the 'ti' function for that table without having to pass it in as a parameter
- [def_printk]
- This creates a 'printk' function that prints all the keys in a table, sorted alphabetically
- [def_printv]
- This creates a 'printv' function that prints all the values in a table, sorted alphabetically
- [def_tcopy]
- This creates a 'tcopy' function that copies all records from one table into another
- [def_printiv]
- This creates a 'printiv' function that prints all the values in a table, in their original order (good for numeric-keyed tables)
- [def_printkv]
- This creates a 'printkv' function that prints all keys and values in a table, sorted by key alphabetically
- [def_ioexec]
- This creates a 'ioexec' function that runs a shell command and returns a table you can store
    - Example: Prints all the .lua files under a directory
"""

```
local ttbFILE = ioexec('find /sdcard/qlua5 -name "*.lua" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)
```

- [def_printio]
- This creates a 'printio' function that runs printiv on the ioexec table
    - Example: printio('ls /storage')

AndroidQLua\MxClasses LoadFile

```
--[under folder /sdcard/qlua5]
--This file can be run by the QLua command "LoadFile" because it uses the Load function instead of the LoadString function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) load(table.concat(ur_table, "\\r"))() end'}
load(table.concat(def_tcompile, "\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  load(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)

AndroidQLua\MxClasses Require Program Module

```
--[under folder /sdcard/qlua5]
--Create subdir share/5.3
--Put in a copy of def.lua
--This file can be run by the QLua command "require" because it uses the LoadString function instead of the Load function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) loadstring(table.concat(ur_table, "\\r"))() end'}
loadstring(table.concat(def_tcompile, "\\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  loadstring(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
--[[
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)
--]]

AndroidQLua\Source Code Editor

"""
[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icons]
- Click button New File (looks like a page with a Plus sign) -> Opens dialog

- [New file dialog]
- Click option Blank file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Enter some text

- [Bottom bar]
- Click button Save (looks like a 3.5" floppy disk)

[SDCard file list]
- Note: The file gets saved in the folder /sdcard/qlua5

AndroidScreenshot

<<glbl_article_list>>

AndroidScreenshot\Screenshot Easy

"""
[Google Play Store app]
- Install app Screenshot Easy by Ice Cold Apps
- Note: Contains ads

AndroidVNC

<<glbl_article_list>>

AndroidVNC\RealVNC remote control Windows O/S

"""
Windows O/S

[https://www.realvnc.com/en/connect/download/viewer/windows/]
- Install app VNC Connect for Windows

[VNC Connect for Windows app]
- Connects to login
- Note: Allows connection by RealVNC's VNC Viewer app on Android O/S

Android O/S

[Google Play Store]
- Install app VNC Viewer by RealVNC Limited

[VNC Viewer app]
- Connects to login
- [Alt tab]
- Use Ctrl-Esc to get to the Windows Start Menu and the Task Bar to change windows

AndroidVNC\Remote Control Android Device

"""
Install app AnyDesk by AnyDesk Software GmbH
- https://play.google.com/store/apps/details?id=com.anydesk.anydeskandroid&hl=en_US&gl=US

Install on both Android devices
- The other installed devices will show when connected to the same WiFi network
- Automatically figures out how to use the controlling Android device's touch screen

AndroidWebDav

<<glbl_article_list>>

AndroidWebDav\BestDAV

"""
Access files on Android device from a networked Windows computer

[Andrdoid OS]
- [Google Play Store]
- Install app WebDAV Server - BestDAV
- - Free or Pro edition

[WebDAV Server]
- [Main page, top bar]
- Note: Folders not listed under the "Folders" button automatically has read-only access via WebDav
- Click button Settings -> nav
- [Settings page]
- Website Home Directory = /storage
- [Main page, bottom bar]
- Click button Start Server
- Note: The server's network URL starts with "http://" and ends with ":8080"
- - Sample = http://192.168.0.15:8080

[Windows computer]
- [browser]
- Address = http://192.168.0.15:8080
- Click link Get the file list -> nav
- Note: The directory shows the "external" SD Card name (if any) and "enc_emulated"
- To see the "internal" /sdcard folder on the android device,
- - Click link "enc_emulated" -> /_dir.cgi?dir=%2Fenc_emulated
- - Edit the address to say /_dir.cgi?dir=%2Femulated/0

- [Windows Explorer]
- Address = \\192.168.0.15@8080\DavWWWRoot
- Note: The directory shows the "external" SD Card name (if any) and "emulated", "enc_emulated", and "self"
- To see the "internal" /sdcard folder on the android device,
- - Click link "emulated" -> http://192.168.0.15:8080/emulated
- - Edit the address to say http://192.168.0.15:8080/emulated/0

btn Delete Cards

<$button>
<$list filter="[tag[ARTICLE]] [tag[IMG]]"><$action-deletetiddler $tiddler=<<currentTiddler>> /></$list>
Del ARTICLE and IMG cards
</$button>

Card filter

\define tag_button(ur_field, ur_tag_name)
<$button>
<$action-setfield $tiddler="$ur_field$" text="$ur_tag_name$"/>
<$action-navigate $to="Tag pairs"/>
<<tag-pill "$ur_tag_name$">>
</$button>
\end

{{ext TW Return}}

<$list variable=on_twcard filter="[<tv-config-toolbar-icons>!match[no]]">
<$button>
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/tag_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/text_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/text_input_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
Clear filters
</$button><br>

Text search: <$edit-text tiddler="$:/state/popup/text_input_e1" field=text default="" placeholder="[Type to search for text 1]" autoHeight=yes tag=input/>
<$edit-text tiddler="$:/state/popup/text_input_e2" field=text default="" placeholder="[Type to search for text 2]" autoHeight=yes tag=input/>
<$button>
<$action-setfield $tiddler="$:/state/popup/text_e1" text={{$:/state/popup/text_input_e1}}/>
<$action-setfield $tiddler="$:/state/popup/text_e2" text={{$:/state/popup/text_input_e2}}/>
Search text
</$button><br>

<$list variable=text_prefix_e1 filter="[[$:/state/popup/text_e1]get[text]else[]]">
<$list variable=text_lowercase_e1 filter="[<text_prefix_e1>lowercase[]]">
<$list variable=text_prefix_e2 filter="[[$:/state/popup/text_e2]get[text]else[]]">
<$list variable=text_lowercase_e2 filter="[<text_prefix_e2>lowercase[]]">
<$list variable=tag_prefix_e1 filter="[[$:/state/popup/tag_e1]get[text]uppercase[]else[]]">
<$list variable=count_any_input filter="[<text_prefix_e1>] [<text_prefix_e2>] [<tag_prefix_e1>] +[each:value[]!match[]count[]]">

<$list variable=tag_list filter="[tags[]each:value[]!prefix[$:]sort[]]">
<$list variable=all_caps_taglist filter="[<tag_list>uppercase[]]">
<$list variable=filter_all_capslist filter="[<tag_list>!match<all_caps_taglist>]">
<$list variable=card_count filter="[tag<tag_list>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>count[]!match[0]]">@@white-space:nowrap;<$macrocall $name=tag_button ur_field="$:/state/popup/tag_e1" ur_tag_name=<<tag_list>> /> ( <<card_count>> )@@
</$list><!--card_count-->
</$list><!--filter_all_capslist-->
</$list><!--all_caps_taglist-->
</$list><!--tag_list
-->

<$list variable=filter_any_input filter="[<count_any_input>!match[0]]">
<$list variable=tag_e1 filter="[search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>tags[]each:value[]!prefix[$:]sort[]]">
<$list variable=all_caps_tage1 filter="[<tag_e1>uppercase[]]">
<$list variable=filter_all_capse1 filter="[<tag_e1>!match<all_caps_tage1>]">
<$list variable=filter_prefix_e1 filter="[<all_caps_tage1>prefix<tag_prefix_e1>]">
<$list variable=card_count filter="[tag<tag_e1>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>count[]]">
<$list variable=filter_card_found filter="[<card_count>!match[0]]">
<$macrocall $name=tag_button ur_field="$:/state/popup/tag_e1" ur_tag_name=<<tag_e1>> />

<$list variable=link_title filter="[tag<tag_e1>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>]">

<<<
<$link to=<<link_title>> /> (<$list variable=disp_tag filter="[<link_title>tags[]sort[]]"> <<disp_tag>> </$list>)

<$list variable=filter_anytext_e1 filter="[<text_prefix_e1>!match[]]">
<$list variable=found_leadingtext_e1 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e1>butlast[]]">

* <$list variable=sample_leadingtext_e1 filter="[<found_leadingtext_e1>split[ ]last[7]join[ ]]">
<$text text=<<sample_leadingtext_e1>> />
''<$text text=<<text_lowercase_e1>> />''
</$list><!--sample_leadingtext_e1-->
<br>
</$list><!--found_leadingtext_e1-->
<$list variable=found_trailingtext_e1 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e1>butfirst[]]">

* <$list variable=sample_trailingtext_e1 filter="[<found_trailingtext_e1>split[ ]first[7]join[ ]]">
''<$text text=<<text_lowercase_e1>> />''
<$text text=<<sample_trailingtext_e1>> />
</$list><!--sample_trailingtext_e1-->
</$list><!--found_trailingtext_e1-->
</$list><!--filter_anytext_e1
-->

<$list variable=filter_anytext_e2 filter="[<text_prefix_e2>!match[]]">
<$list variable=found_leadingtext_e2 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e2>butlast[]]">

* <$list variable=sample_leadingtext_e2 filter="[<found_leadingtext_e2>split[ ]last[7]join[ ]]">
<$text text=<<sample_leadingtext_e2>> />
''<$text text=<<text_lowercase_e2>> />''
</$list><!--sample_leadingtext_e2-->
<br>
</$list><!--found_leadingtext_e2-->
<$list variable=found_trailingtext_e2 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e2>butfirst[]]">

* <$list variable=sample_trailingtext_e2 filter="[<found_trailingtext_e2>split[ ]first[7]join[ ]]">
''<$text text=<<text_lowercase_e2>> />''
<$text text=<<sample_trailingtext_e2>> />
</$list><!--sample_trailingtext_e2-->
</$list><!--found_trailingtext_e2-->
</$list><!--filter_anytext_e2
-->

<<<
</$list><!--link_title-->
</$list><!--filter_card_found-->
</$list><!--card_count-->
</$list><!--filter_prefix_e1-->
</$list><!--filter_all_capse1-->
</$list><!--all_caps_tage1-->
</$list><!--tag_e1-->
</$list><!--filter_any_input-->
</$list><!--count_any_input-->
</$list><!--tag_prefix_e1-->
</$list><!--text_lowercase_e2-->
</$list><!--text_lowercase_e1-->
</$list><!--text_prefix_e2-->
</$list><!--text_prefix_e1-->
</$list><!--on_twcard-->

[[Search All Code |View All Code]]

[[___|Recent Entries]]

ChromeBrowser

<<glbl_article_list>>

ChromeBrowser\Browse Local Folders

"""
Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome

[Google Chrome app]
- [Windows O/S]
- Navigate to file:///C:/
- [Android O/S]
- Navigate to file:///sdcard/

- [Directory list]
- Select which sub-folder you want to bookmark
- [Navigation bar, Top-right icons]
- Click button Bookmark Page (looks like a star shape) -> Opens dialog
- [Bookmark Added dialog]
- Name = UrShortName
- Click button Done -> Closes dialog
- [Navigation bar]
- Address = UrShortName -> Shows suggestions
- [Suggestion list]
- Select the suggested link -> Navigates page

ChromeBrowser\Command Line Options

"""
The command line options are usually two hyphens followed by a keyword

- Note: The incognito option starts the browser with an open Incognito window
"""

```
–incognito
```

"""
- Note: Google Chrome Portable has these parameters automatically included when calling the Chrome.exe program.
"""

```
–user-data-dir="%TEMP%"
–disk-cache-dir="%TEMP%\GoogleChromePortable\Cache"
```

"""
To override the user data and all the cache directories:

- Find the INI file in the PortableApp sub-directory
"""

```
GoogleChromePortable\Other\Source\GoogleChromePortable.ini
```

"""
- Copy it to the program main directory
"""

```
GoogleChromePortable\GoogleChromePortable.ini
```

"""
- [Edit the file]
- CacheInTemp = false
- Save file
- Note: When you restart Google Chrome Portable, cached files will be stored under the program's folder
"""

```
C:\TJBF\zPortableInstalls\Chrome\Data\profile\Default\*Cache\
```

ChromeBrowser\Turn off Chrome spell check highlighting

"""
[Google Chrome app]
- [Top-right icons]
- Click the three-dots menu, option Settings -> Navigates page
- [Settings page[
- search for Language -> Filters results
- [Languages section]
- checkbox Spell check = clear -> Chrome will not highlight spelling errors

Code Samples

{{ext TW Return}}

<<list-links filter:"[tag[DOC]sort[title]]">>

[[___|Recent Entries]]

css alternating-rows

.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}

DivPop btn

<$list variable=cur_card filter="[all[current]]">
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=<<cur_card>>/>
<$action-sendmessage $message="tm-close-tiddler" $param="pop_right"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{DivPop.svg}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text="Popup over Sidebar"/></span>
</$list>
</$button>
</$list>

DivPop glbl

<$list variable=cur_divpop_card filter="[{$:/state/popup/DivPopTitle}is[tiddler]]">
<div style="
position: fixed;
top: 0px;
right: 0px;
width: 350px;
border: 3px solid;
background: white;
bottom: 0%;
">
<div style="overflow-y: scroll; height: 100%;">
<$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
close
</$button>
&nbsp;&nbsp;&nbsp;<$reveal type="match" state="$:/state/popup/$ur_pk$" text="show"><$button set="$:/state/popup/$ur_pk$" setTo="hide">show</$button>&nbsp;&nbsp;&nbsp;<$link to=<<cur_divpop_card>> ><<cur_divpop_card>>
</$link>
<$list variable=cur_text filter="[<cur_divpop_card>get[text]]">
<$codeblock code=<<cur_text>> /></$list>
</$reveal>
<$reveal type="nomatch" state="$:/state/popup/$ur_pk$" text="show"><$button set="$:/state/popup/$ur_pk$" setTo="show">code</$button>&nbsp;&nbsp;&nbsp;<$link to=<<cur_divpop_card>> ><<cur_divpop_card>>
</$link>
<$tiddler tiddler=<<cur_divpop_card>> >
<$transclude mode="block" />
</$tiddler>
</$reveal>
</div>
</div>
</$list>

Excel VBA

<<glbl_article_list>>

Excel VBA\Get Worksheet

```
Dim wksDATA As Worksheet
Set wksDATA = Application.ActiveSheet
wksDATA.Cells(2,2).Value = "Hi"

'Press F5 to run the macro
'Note: Cell B2 says "Hi"

Excel VBA\New Macro

"""
[Microsoft Excel application]
- [Ribbon menus]
- View menu, option Record Macro -> Starts recording
- View menu, option Stop Recording -> Stops recording
- View menu, option Macros -> Opens dialog

[Macro list]
- Click button Edit Macro -> Opens window

[VBA Editor]
- You can change the name of the macro and add commands
- Close the editor

[Microsoft Excel application]
- Save the file as a Macro-Enabled workbook (mwb)

Excel VBA\Power Exponent

"""
Make sure you put a space between the power operator (^) and the numbers

- CalcResult = 2^5
- Note: This gives a compilation error on 64-bit Excel

- CalcResult = 2 ^ 5
- Note: CalcResult = 32

ext ALAorg Citations bookmarklet

http://www.ala.org/tools/article/ala-techsource/%E2%80%9Ccitethis%E2%80%9D-building-javascript-bookmarklet-creates-citations-sharing-web

ext Apple.com Safari Meta tags

https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html

ext CodeAcademy DocType

https://discuss.codecademy.com/t/why-we-type-before-doctype-what-is-the-role-of-in-doctype-html/60880/3

ext DeveloperSettings HTM

VBNet_Project\DeveloperSettings\Developer Settings App.html

ext DeveloperSettings ZIP

VBNet_Project\DeveloperSettings\DeveloperSettings.zip

ext Empty Wiki Setup

TW Project\Empty Wiki\Empty Wiki.htm

ext FileFormat.Info UnicodeInput

https://www.fileformat.info/tool/unicodeinput/index.htm

ext FileFormat.Info UnicodeInput.ZIP

https://www.fileformat.info/tool/unicodeinput/unicodeinput.zip

ext GitHub LukeHorvat Computed Style to Inline

https://github.com/lukehorvat/computed-style-to-inline-style

ext GoogleDevelopers FullScreen web app

https://developers.google.com/web/fundamentals/native-hardware/fullscreen/

ext HTML.com DocType

https://html.com/tags/doctype/

ext JavaScript Closures

http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html

ext JavaScript Strict Mode

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

ext JavaScript This Parameter

http://blog.niftysnippets.org/2008/03/mythical-methods.html

ext JTFAssociates MOTW

https://jtfassociates.com/using-the-mark-of-the-web-motw/

ext MathiasBynens Rel Icon

https://mathiasbynens.be/notes/rel-shortcut-icon

ext MetaTags.org Generator

https://www.metatags.org/all-meta-tags-overview/meta-name-generator/

ext Microsoft DotNet Char ConvertToUTF32

https://docs.microsoft.com/en-us/dotnet/api/system.char.converttoutf32?view=net-5.0#System_Char_ConvertToUtf32_System_String_System_Int32_

ext Microsoft RemoteDesktop Enable

https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-allow-access

ext Mozilla.org META tags

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name

ext MozillaDeveloper CSS Comment

https://developer.mozilla.org/en-US/docs/Web/CSS/Comments

ext MozillaDeveloper Strict mode

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

ext MxBase Classes

VBNet_Project/MxBase/MxBase%20Classes.html

ext Project Check app

TW Project\Checkapp\Checkapp.htm

ext PSU.edu LangTag

https://accessibility.psu.edu/foreignlanguages/langtaghtml/

ext Regexp Filter with brackets

https://tiddlywiki.narkive.com/T5403O4p/tw5-regexp-for-matching-a-tag-tiddlytweeter#post7

ext Regular Expression Quantifiers

https://www.rexegg.com/regex-quantifiers.html

ext Roman to Decimal ZIP

VBNet_Project\Examples\Roman_To_Decimal.zip

ext Shuffle List Entries

TiddlyWiki_Code\Snapshot\mklauber TWPlugin Shuffle.txt.html

ext SitePoint Exports Node.JS

https://www.sitepoint.com/understanding-module-exports-exports-node-js/

ext SO.com RunTime Net 4.5

https://stackoverflow.com/questions/8517159/how-do-i-detect-at-runtime-that-net-version-4-5-is-currently-running-your-code

ext SQLite Blob text

https://stackoverflow.com/questions/15366594/convert-hex-to-text-using-sqlite

ext SQLite DB Browser

https://sqlitebrowser.org/dl/

ext SQLite Language functions

https://sqlite.org/lang_corefunc.html

ext SQLite schema information

https://stackoverflow.com/questions/6460671/sqlite-schema-information-metadata

ext SQLite Top 5 Records

https://stackoverflow.com/questions/2728999/how-to-get-top-5-records-in-sqlite

ext StackOverflow CSS location

https://stackoverflow.com/questions/1642212/whats-the-difference-if-i-put-css-file-inside-head-or-body

ext StackOverflow Hide Parent Show Child tag

https://stackoverflow.com/questions/12956937/display-html-child-element-when-parent-element-is-displaynone

ext StackOverflow Meta UA-Compatible

https://stackoverflow.com/questions/6771258/what-does-meta-http-equiv-x-ua-compatible-content-ie-edge-do#:~:text=The%20X%2DUA%2DCompatible%20meta%20tag%20allows%20web%20authors%20to,meta%20tag%20in%20certain%20circumstances.

ext Tiddly Wiki Home Button source code

https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/PageControls/home.tid

ext TiddlyWiki Save Button source code

https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/PageControls/savewiki.tid

ext TiddlyWiki TopBar Menu

https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/TopRightBar/menu.tid

ext TW Addon Text Replace

TiddlyWiki_Code\AddOns\Text Replace Bar.htm

ext TW Create Javascript Plugin

https://sudonull.com/post/97468-How-to-write-a-plugin-for-TiddlyWiki

ext TW Features

TiddlyWiki_Code\Features\TW Features.htm

ext TW JS Pretty

TW Project\JS_Pretty\TW JS Pretty.htm

ext TW Manual

TiddlyWiki_Code\Snapshot\TheBook - The TiddlyWiki Manual.txt.html

ext TW Return

\define TW_Return(ur_url, ur_link_title)
<div style="float:right"><a href="$ur_url$"> ($ur_link_title$)</a></div>
\end
<$list variable=found_index filter="[{$:/info/url/full}split[/]count[]subtract[1]]">
<$list variable=skip_html filter="[<tv-config-toolbar-icons>match[no]]">
<$list variable=return_url filter="[{$:/info/url/full}split[/]butfirst<found_index>first[]split[.html]join[.htm]addprefix[src/]]">
<$macrocall $name=TW_Return ur_url=<<return_url>> ur_link_title="TiddlyWiki view of website" />
</$list><!--found_html-->
</$list><!--skip_html-->
<$list variable=found_html filter="[<tv-config-toolbar-icons>!match[no]]">
<$list variable=return_url filter="[{$:/info/url/full}split[/]butfirst<found_index>first[]split[.html]join[.htm]split[.htm]join[.html]addprefix[../]]">
<$macrocall $name=TW_Return ur_url=<<return_url>> ur_link_title="Static HTML view of website" />
</$list>
</$list><!--found_html-->
</$list><!--found_index-->

ext TW Snapshot Review

TiddlyWiki_Code\Snapshot\Browse Code tiddlywiki_v5d01d23pre-release.htm

ext TW Snapshot v5d01d23 empty

TW Project\Snapshot\tw_empty_v5d01d23.html

ext TW Snapshot v5d01d23 main-site

TW Project\Snapshot\tiddlywiki_v5d01d23_main-site.html

ext TW Snapshot v5d01d23 pre-release

TW Project\Snapshot\tiddlywiki_v5d01d23_pre-release.html

ext TW Snapshot v5d01d23 update

TW Project\Snapshot\tiddlywiki_v5d01d23_update.html

ext Unicode Block 00-Basic Latin

https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)

ext Unicode Block 01-Latin Supplement

https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)

ext Unicode Block Planes

https://en.wikipedia.org/wiki/Plane_(Unicode)

ext Unicode Character Database

http://www.unicode.org/Public/UCD/latest/

ext Unicode Code Block List

https://en.wikipedia.org/wiki/Unicode_block

ext VBNetScript.EXE

VBNet_Project\VBNetscript\VBNetScript_EXE.zip

ext VBNetScript.SLN

VBNet_Project\VBNetscript\VBNetScript_Project.zip

ext W3.org HTML401 Meta

https://www.w3.org/TR/html401/struct/global.html#h-7.4.4

ext W3.org HTML401 Profiles

https://www.w3.org/TR/html401/struct/global.html#profiles

ext W3Schools DocType

https://www.w3schools.com/tags/tag_doctype.asp

ext W3Schools Head tag

https://www.w3schools.com/tags/tag_head.asp

ext W3Schools Meta HTTP-EQUIV

https://www.w3schools.com/tags/att_meta_http_equiv.asp

ext W3Schools NoScript tag

https://www.w3schools.com/tags/tag_noscript.asp

ext WestWindCom Net Core Runtime

https://weblog.west-wind.com/posts/2018/Apr/12/Getting-the-NET-Core-Runtime-Version-in-a-Running-Application

ext WHATWg.org Link Icon

https://html.spec.whatwg.org/multipage/links.html#rel-icon

ext Wiki Move HTM

VBNS_Project\Wiki_Move\Wiki Move HTM.htm

ext Windows Alt-Numpad Unicode

https://conemu.github.io/en/AltNumpad.html

ext Windows Environment Variable List

https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables#bkmk-1

ext Windows Terminal Unicode Support

https://devblogs.microsoft.com/commandline/introducing-windows-terminal/

ext WindowsCLI Unicode Support

https://www.generacodice.com/en/articolo/203149/How-to-use-unicode-characters-in-Windows-command-line

FFMPeg

<<glbl_article_list>>

FFMPeg\Extract Captions file

```
chcp 65001
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" "C:\UrPath\UrFile.srt"
pause

FFMPeg\Extract JPG files

"""
[ffmpeg.exe command-line options]
- `-ss 05:00 -t 10:00` means start at 5min and end 10min later at 15min
- `-r 1` means 1 frame per second
- `-r 0.25` means 1 frame every 4 seconds
- `-r 0.083` means 1 frame every 12 seconds, or 5 frames per minute, 50 frames out of every ten minutes, or 300 frames every hour

- IrfanView can create a portrait contact sheet with 5 columns, representing one min of video per row, 10 rows per page showing 10 minutes of video
- IrfanView can create a landscape contact sheet with 7 columns is one 3 min per 2 rows, 7 rows per page showing 10.5 minutes of video, two pages showing 21 minutes

- Open on thumbnail image with IrfanView, select File menu Thumbnails option
- Select all files in the folder, select File menu Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

"""

```
chcp 65001
rem -ss 05:00 -t 10:00 means start at 5min and end 10min later at 15min
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" -r 0.083 -s 320x180 "UrPath\UrSubdir\output_%%04d.jpg"


Font Size

<$list variable=cur_entry filter="[all[tiddlers]!suffix[.js]!suffix[.css]!match[$:/core]!prefix[$:/config/]!prefix[$:/DefaultTiddlers]!prefix[$:/Import]!match[$:/isEncrypted]!prefix[$:/language/]!prefix[$:/theme]!prefix[$:/temp/]!prefix[$:/status/]!match[$:/StoryList]!match[$:/HistoryList]!match[$:/SiteTitle]!match[$:/SiteSubtitle]!prefix[$:/state/]count[]]">
Specific prefix filter: <<cur_entry>> cards
</$list>

<$list variable=cur_entry filter="[all[tiddlers]!is[system]] [prefix[$:/positivesigner]] +[count[]]">

Non-system plus system PositiveSigner filter: <<cur_entry>> cards
</$list>


<$button>
<$list variable=cur_card filter="[!is[system]!prefix[Draft of]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[append[COPY]]"/>
</$list>
Append COPY tag to all non-system cards
</$button><br>

<$button>
<$list variable=cur_card filter="[tag[COPY]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[remove[COPY]]"/>
</$list>
Remove COPY tag from all cards
</$button><br>


<$button>
{{keyboard action FontLarge}}
Big Font
</$button>

<$button>
{{keyboard action FontNormal}}
Normal Font
</$button>

[[Panel]]

!!Cards where has[tags] does not work

<$list variable=cur_card filter="[is[tiddler]]">
<$list variable=has_tags_test filter="[<cur_card>!has[tags]count[]] [<cur_card>has[tags]count[]] +[sum[]match[0]]">

<$link to=<<cur_card>> />
</$list><!--has_tags_test-->
</$list><!--cur_card-->

!!Cards with no tags

<$list variable=cur_card filter="[!is[system]is[tiddler]!has[tags]!prefix[Draft of]!prefix[$:/state/]!prefix[$:/library/]!prefix[$:/boot/]!prefix[$:/temp/]!match[$:/core]!match[$:/Import]!match[$:/isEncrypted]!match[$:/SiteSubtitle]!match[$:/SiteTitle]!prefix[$:/status/]!match[$:/StoryList]!match[$:/HistoryList]!match[$:/theme]!match[$:/themes/tiddlywiki/snowwhite]!match[$:/themes/tiddlywiki/vanilla]]">
<$list variable=has_parent_card filter="[<cur_card>split[\]count[]match[1]]">

<$link to=<<cur_card>> />
</$list><!--has_parent_card-->

<$list variable=has_parent_card filter="[<cur_card>split[\]count[]!match[1]]">
<$list variable=parent_card_exists filter="[<cur_card>split[\]first[]!is[tiddler]]">

<$link to=<<cur_card>> />
</$list><!--parent_card_exists-->
</$list><!--has_parent_card-->
</$list><!--cur_card-->


[[parm SkipSaveExportHTML]]

[[btn Delete Cards]]

GitCLI

<<glbl_article_list>>

GitCLI\Checkout hash

```
@echo off
SET ur_repo=
SET ur_branch=
"C:\UrPath\git.exe" -C %ur_repo% checkout -b test-branch %ur_branch%

rem Use GitHub Desktop to delete the branch

GitHubDesktop

<<glbl_article_list>>

GitHubDesktop\Git executable

"""
When GitHub Desktop is installed, the Git.exe program is placed in the %APPDATA% folder. There is one sub-directory for each version of Git that has been downloaded. Look for the latest version-numbered folder.
"""

```
C:\Users\UrUser\AppData\Local\GitHubDesktop\app-UrVersion
```

"""
Under the app-UrVersion folder, find the Git.exe program
"""

```
app-UrVersion\resources\app\git\cmd\git.exe

GoogleContacts

<<glbl_article_list>>

GoogleContacts\Export as CSV

"""
[https://contacts.google.com/]
- [Left-side menu]
- Click button Export -> Opens dialog
- Export contacts = Contacts (total count)
- Export as = Google CSV
- Click button Export -> Downloads file, Closes dialog

[CSV file]
- Header fields =
"""

```
Name
Given Name
Additional Name
Family Name
Yomi Name
Given Name Yomi
Additional Name Yomi
Family Name Yomi
Name Prefix
Name Suffix
Initials
Nickname
Short Name
Maiden Name
Birthday
Gender
Location
Billing Information
Directory Server
Mileage
Occupation
Hobby
Sensitivity
Priority
Subject
Notes
Language
Photo
Group Membership
E-mail 1 - Type
E-mail 1 - Value
E-mail 2 - Type
E-mail 2 - Value
Phone 1 - Type
Phone 1 - Value
Phone 2 - Type
Phone 2 - Value
Address 1 - Type
Address 1 - Formatted
Address 1 - Street
Address 1 - City
Address 1 - PO Box
Address 1 - Region
Address 1 - Postal Code
Address 1 - Country
Address 1 - Extended Address
Organization 1 - Type
Organization 1 - Name
Organization 1 - Yomi Name
Organization 1 - Title
Organization 1 - Department
Organization 1 - Symbol
Organization 1 - Location
Organization 1 - Job Description
Relation 1 - Type
Relation 1 - Value
Website 1 - Type
Website 1 - Value
```

- Header line =

```
Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initials,Nickname,Short Name,Maiden Name,Birthday,Gender,Location,Billing Information,Directory Server,Mileage,Occupation,Hobby,Sensitivity,Priority,Subject,Notes,Language,Photo,Group Membership,E-mail 1 - Type,E-mail 1 - Value,E-mail 2 - Type,E-mail 2 - Value,Phone 1 - Type,Phone 1 - Value,Phone 2 - Type,Phone 2 - Value,Address 1 - Type,Address 1 - Formatted,Address 1 - Street,Address 1 - City,Address 1 - PO Box,Address 1 - Region,Address 1 - Postal Code,Address 1 - Country,Address 1 - Extended Address,Organization 1 - Type,Organization 1 - Name,Organization 1 - Yomi Name,Organization 1 - Title,Organization 1 - Department,Organization 1 - Symbol,Organization 1 - Location,Organization 1 - Job Description,Relation 1 - Type,Relation 1 - Value,Website 1 - Type,Website 1 - Value
```

- Sample data 1

```
.me,.me,,,,,,,,,,,,,,,,,,,,,,,,,,,Imported 8/5/16 ::: * myContacts,,,,,Mobile,5554443333 ::: 16665554444,,,,,,,,,,,,,,,,,,,,,,,
```

- Sample data 2

```
UrContactName,UrContactFirstName,,UrContactLastName,,,,,,,,,,,,,,,,,,,,,,,,,* myContacts,,,,,Mobile,(444) 333-2222,,,,,,,,,,,,,,,,,,,,,,,
```

GoogleGmail

<<glbl_article_list>>

GoogleGmail\Export as MBOX

"""
[https://takeout.google.com/]
- [Products section]
- Click link Deselect All
- [Mail section]
- checkbox = set
- [End of Page section]
- Click button Next Step -> Navigates section
- [Choose file type, frequency & destination]
- Frequency = Export once
- File type = .zip
- File size = 2 GB
- Click button Create Export -> Navigates section
- [Export Progress]
- Note: Google is creating a copy of files from Mail. This process can take a long time (possibly hours or days) to complete. You'll receive an email when your export is done.

[https://mail.google.com/]
- [Message with title "Archive of Google data requested"]
- Note: You can ignore the message or click the link to verify it was you
- [Message with title "Your Google data is ready to download"]
- Click button Download Your Files -> Opens tab

[Google Takeout form]
- Re-enter your password
- [Record where Export = Mail]
- Note: The size of the export file is also in the Export column
- Click button Download -> Downloads file
- Note: The file may take a long time to download depending on your internet connection and the size of the file

[ZIP file]
- Extract the ZIP file to a folder

[Takeout folder]
- Open the archive_browser.html -> Opens browser

[Archive Browser page]
- [File Formats tab]
- Note: An mbox is a way of storing mail messages and is supported by common mail clients like Microsoft Outlook, Mozilla Thunderbird, and Apple's Mail program. These files are most easily opened by a dedicated mail client like those listed above

[Takeout\Mail folder]
- [All mail Including Spam and Trash.mbox]
- Use Mozilla Thunderbird to read the MBOX file
- OR Split this file into smaller text files... [[somehow |VBNetCode\Copy File Lines]]
- Format:

Record Start = Leading "From " <- Including the space
Tags = "WordsWithoutSpaces:" <- no spaces in tag name
Tag continuation values = " Every Line With Leading Space Or Tab After Tag Name"
Email Content = "First line that is not a tag or tag continuation -> through last line before next leading " "From "

GoogleGmail\MBOX file parsing test

```
start "" "%~dp0\MxClasses\VBNetScript.exe" /path=%0 & exit
MxClasses\MxBaseEc12.vb
RetVal = Mx.Want.TextFile_Split_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.TextFile_Split_errhnd
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub TextFile_Split(ret_message As Strap)
			Dim tabchr = CHR(9)
			Dim flnDATA = FileNamed().d("C:\Users\Dad\Downloads\Takeout\Mail\All mail Including Spam and Trash.mbox")
			Dim intLINE_COUNT = 0
			Dim sdaPREFIX_SKIPPED = New Sdata
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), False, gUTF8_FileEncoding)
				Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
				    Dim bolINCLUDE_INDENTED_LINES = False
					Dim bolHTML_TEXT = False
					Dim bolPLAIN_TEXT = False
					Dim bolSKIP_TEXT = False
					While stmDATA.EndOfStream = False
						Dim strLINE = stmDATA.ReadLine()
						If strLINE.Length = 0 Then
						
						ElseIf Left(strLINE, 5) = "From " AndAlso
						  Len(strLINE) = 59 Then
						    bolINCLUDE_INDENTED_LINES = False
							bolHTML_TEXT = False
							bolPLAIN_TEXT = False
							bolSKIP_TEXT = False
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine(strLINE)
							intLINE_COUNT += 1
						
						ElseIf bolSKIP_TEXT Then
						
						ElseIf bolPLAIN_TEXT Then
							If strLINE.Trim.Length > 0 Then
								Dim bolCUR_HTML = False
								Dim intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									bolCUR_HTML = True
									
									End If
								
								If Left(strLINE, 16) = "X-Attachment-Id:" OrElse
								  Left(strLINE, 32) = "Content-Transfer-Encoding:base64" Then
									bolSKIP_TEXT = True
									
									End If 'strLINE
								
								If bolHTML_TEXT = False Then
									stmOUT_FILE.WriteLine(strLINE)
									intLINE_COUNT += 1
								
								ElseIf bolCUR_HTML Then
									Dim strTEXT = strLINE
									While intFOUND_SPRTR > 0
										Dim strPREFIX = Mid(strTEXT, 1, intFOUND_SPRTR - 1)
										Dim strTAG = Mid(strTEXT, intFOUND_SPRTR)
										intFOUND_SPRTR = InStr(strTAG, ">")
										If intFOUND_SPRTR = 0 Then
											strTEXT = strPREFIX
										
										Else
											strTEXT = strPREFIX & Mid(strTAG, intFOUND_SPRTR + 1)
											intFOUND_SPRTR = InStr(strTEXT, "<")
											
											End If 'intFOUND_SPRTR
										
										End While 'intFOUND_SPRTR
									
									If strTEXT.Trim.Length > 0 Then
										stmOUT_FILE.WriteLine(strTEXT)
										intLINE_COUNT += 1
										
										End If
									
									End If 'intFOUND_SPRTR
									
								End If 'strLINE
							
						ElseIf (Left(strLINE, 1) = s OrElse Left(strLINE, 1) = tabchr) AndAlso
						  bolINCLUDE_INDENTED_LINES Then
							'stmOUT_FILE.WriteLine(strLINE)
							'intLINE_COUNT += 1
						    
						Else 'strLINE
						    bolINCLUDE_INDENTED_LINES = False
							Dim strPREFIX = mt
						    Dim intFOUND_SPRTR = InStr(strLINE, ":")
							If intFOUND_SPRTR > 0 Then
							    strPREFIX = Mid(strLINE, 1, intFOUND_SPRTR)
								If InStr(strPREFIX, tabchr) > 0 OrElse
								  InStr(strPREFIX, s) > 0 Then
									strPREFIX = mt
									
									End If
								
								End If
							
							If strPREFIX = "Content-Type:" OrElse
							  strPREFIX = "Subject:" OrElse
							  strPREFIX = "To:" OrElse
							  strPREFIX = "Date:" OrElse
							  strPREFIX = "From:" Then
								bolINCLUDE_INDENTED_LINES = True
								stmOUT_FILE.WriteLine(strLINE)
								intLINE_COUNT += 1
							
							ElseIf Right(strPREFIX, 1) = ":" Then
								bolINCLUDE_INDENTED_LINES = True
								If sdaPREFIX_SKIPPED.Contains(strPREFIX) = False Then
									sdaPREFIX_SKIPPED.d(strPREFIX)
									
								    End If
							
							ElseIf strPREFIX = "" Then
							    bolPLAIN_TEXT = True
								intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									
									End If
								
								End If 'strPREFIX
							
							End If 'strLINE
						
						If intLINE_COUNT >= 100000 Then
							Exit While
							
							End If
						
						End While 'stmDATA
					
					End Using 'stmDATA
				
				End Using 'stmOUT_FILE
			
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("PREFIX_SKIPPED.TXT"), False, gUTF8_FileEncoding)
				Call sdaPREFIX_SKIPPED.Sort()
				For Each strENTRY In sdaPREFIX_SKIPPED
					stmOUT_FILE.WriteLine(strENTRY)
					
					Next strENTRY
				
				End Using 'stmOUT_FILE

			ret_message.Clear.d(intLINE_COUNT.ToString)
			
			End Sub 'TextFile_Split

        Public Shared Function TextFile_Split_errhnd() As Strap
            Dim stpRET = Strapd()
            TextFile_Split_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call TextFile_Split(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'TextFile_Split_errhnd
    End Class 'Want
End Namespace 'Mx

GooglePlay

<<glbl_article_list>>

GooglePlay\Share purchased apps with another account

"""
[Play Store app]
- [Top-left icon]
- Click the three-lines menu, option `Family Library` -> Navigates page
- Note: There are two Sections
- - `Added by [Other]`
- - `Added by you`

If the purchased app you want to share is not shown under the `Added by You` section, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option `My apps & games` -> Navigates page
- [Installed tab, or Library tab]
- Choose an app you purchased -> Navigates page
- [App page]
- Note: The checkbox Family Library is a toggle switch
- checkbox Family Library = set -> The app is available to all `Family` logins

If the 'Family' logins does not contain the account you want to access your shared app, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option `Account` -> Navigates page
- [Family tab]
- Click button Manage family members -> Opens dialog
- [Family dialog]
- Click button Invite family members -> Opens dialog
- [Verify CVC dialog]
- Enter your credit card number's CVC number
- Click button Verify -> Closes dialog, Opens dialog
- [Send Invitations dialog]
- Select a contact
- Click button Send

[Added Account email]
- Click the invitation link -> Navigates page
- Note: The Added Account can now use the Play Store app to install the Family Library shared app

GooglePlusCodes

<<glbl_article_list>>

GooglePlusCodes\Find a Plus Code

"""
[https://plus.codes/map/]
- [Search box, Left-side icon]
- Click the three-lines menu, option Satellite -> Refreshes window
- Click the three-lines menu, option Grid -> Refreshes window
- [Navigate to location]
- When the mouse icon is a hand, double-click to Zoom in
- Each time you click, the location will show as 8 characters, a plus sign, and two suffix characters
- - Example: 73F6C9JH+HR
- The last two Zoom levels allow you to select a single Plus Code rectangle, which has three suffix characters after the plus sign
- - Example: 73F6C9JH+HR7
- Copy the browser address bar
- - Example: https://plus.codes/73F6C9JH+HR7

- Note: You can email the page link to someone
- - They will have to turn on the satellite and / or grid options again

- Note: You can use the browser to bookmark the current page
- - Android O/S Chrome can create a desktop shortcut to the current website page (when not in Incognito mode)

- Note: The plus codes are 8 characters, a plus, and two or three suffix characters
- - The bottom of the Plus.Codes website's map only temporarily shows the three suffix characters after you click, quickly reverting to show only two suffix characters
- - You can still see all three suffix characters in the address bar

- [Bottom location code bar, Right-side icon]
- Click button Navigate (looks like a Right-Turn Only road sign) -> Navigates to Google Maps website
- Note: Android O/S Chrome app will ask to Stay On Web or Use The App
- - Click button Use The App to open the Google Maps app

HTML CSS

<<glbl_article_list>>

HTML CSS\Comment Declaration

!! HTML 5 document

* Declaration Name = `--`
* Content = unprocessed text, except for the character sequence double-hyphen close-tag ( `-->` )
* Note: HTML declarations are not tags, because the have an exclamation mark ( `!` ) before the declaration name / code
* Note: XML documents have a requirement that a double-hyphen ( `--` ) must itself be doubled ( `----` ) when used in a comment declaration, but HTML 5 has no such requirement


!! Sample code for HTML 5 Comment

```
<!-- a text editor can see the comment text -->
```


HTML CSS\Comment MOTW Declaration

!! HTML document viewed in Internet Explorer

* Comment text sequence:

<<<
* `<!--` and optional whitespace
* `saved from url=(`
* the number of characters in the URL string (including the trailing backslash)
* `)`
* the URL string
* optional whitespace and `-->`
<<<

* HTML documents viewed in Internet Explorer show a warning message due to active content, or has a specifically crafted HTML Comment Declaration that names the root URL of the website it is being hosted on
* Note: If this is for a new site, or if the domain is not known, you can use `about:internet` as a valid URL

<<ext "JTFAssociates MOTW">>

!!Sample code

```
<!-- saved from url=(0014)about:internet -->
```

HTML CSS\Compatibility Meta tags

!! Declare compatibility version of Microsoft Internet Explorer web browser

* tag name = `meta`
* `http-equiv` attr = `X-UA-Compatible`
* `content` attr = `IE=Edge` or (`IE=11`, `IE=EmulateIE11`, and similar version number pairs)
* Note: Use this tag if you need features specific to an older version of IE like IE9 or IE8
* Note: If you only support the latest browsers (IE11 and/or Edge) then this tag will not affect the web page's behavior until another version is created

<<<
Internet Explorer begins interpreting markup using the latest version. When Internet Explorer encounters the X-UA-Compatible META tag it starts over using the designated version's engine. This is a performance hit because the browser must stop and restart analyzing the content.
<<<

<<ext "StackOverflow Meta UA-Compatible">>

!! Sample code

```
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
```

<<<
`content="IE=Edge" ` mode tells Internet Explorer to display content in the highest mode available. With Internet Explorer 9, this is equivalent to IE9 mode. If a future release of Internet Explorer supported a higher compatibility mode, pages set to edge mode would appear in the highest mode supported by that version. Those same pages would still appear in IE9 mode when viewed with Internet Explorer 9.
<<<

!! Specify web application runs in full-screen mode on Apple devices

* tag name = `meta`
* `name` attr = `apple-mobile-web-app-capable`
* `content` attr = `yes`
* Note: The default behavior is to use Safari to display web content
* Note: You can determine whether a webpage is displayed in full-screen mode using the window.navigator.standalone Boolean JavaScript property

<<ext "Apple.com Safari Meta tags">>

!! Sample code

<<<
<meta name="apple-mobile-web-app-capable" content="yes" />
<<<

!! Specify the Full Screen's status bar style on Apple devices

* tag name = `meta`
* `name` attr = `apple-mobile-web-app-status-bar-style`
* `content` attr = `default`, `black`, `black-translucent`
* Note: If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar
* Note: This meta tag has no effect unless you first specify full-screen mode as described in apple-apple-mobile-web-app-capable

<<ext "Apple.com Safari Meta tags">>

!! Sample code

```
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
```

!! Leave original formatting of telephone-number formatted strings 

* tag name = `meta`
* `name` attr = `format-detection`
* `content` attr = `telephone=no`
* Note: By default, Safari on iOS detects any string formatted like a phone number and makes it a link that calls the number

<<ext "Apple.com Safari Meta tags">>

!! Sample code

```
<meta name="format-detection" content="telephone=no" />
```

!! Specify web application runs in full-screen mode on Apple devices

* tag name = `meta`
* `name` attr = `mobile-web-app-capable`
* content = `yes`
* Note: This tells the browser to launch the page fullscreen when the user has added it to the home screen
* Note: A better option is to use the Web App Manifest for Chrome, Opera, Firefox, and Samsung browsers

<<ext "GoogleDevelopers FullScreen web app">>

!! Sample code

```
<meta name="mobile-web-app-capable" content="yes"/>
```

HTML CSS\CSS Style definitions

!! Place a CSS style-sheet in the HTML document

* tag name = `style`
* `type` attr = `text/css`
* Note: The most recent versions of the HTML spec now permits the &lt;style> tag within body elements
* Note: Putting CSS in body means it is loaded later and the browser starts drawing the interface faster
* Note: Putting CSS in body can decrease page performance due to possible reflows/repaints once the browser hits styles further down in the page tree

<<ext "StackOverflow CSS location">>

!! Sample code

```
<style type="text/css">
```

!! Place a comment inside of a CSS style-sheet

* Start CSS comment text with forward-slash asterisk ( `/*` )
* End CSS comment text with asterisk forward-slash ( `*/` )

<<ext "MozillaDeveloper CSS Comment">>

!! Sample code

```
<style type="text/css">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>
```

HTML CSS\Declare document Content type


HTML CSS\DocType Declaration

!! HTML 5 document

* Declaration Name = `DOCTYPE`
* Content = `html`
* Note: HTML declarations are not tags, because the have an exclamation mark ( `!` ) before the declaration name / code
* Note: This should be the first non-whitespace characters in the document to be compliant with HTML standards
* Note: HTML5 documents don't really need a DOCTYPE as there is no HTML5 DTD for browsers to refer to, but it is used in HTML5 to make sure the browser doesn’t switch into “quirks” mode and remains in full standards mode

<<ext "W3Schools DocType">>

<<ext "HTML.com DocType">>

<<ext "CodeAcademy DocType">>

!! Sample code for HTML 5 declaration

```
<!DOCTYPE html>
```


HTML CSS\Head section

!! Set metadata values for interpreting document contents
* The &lt;head> element is a container for metadata (data about data) and is placed between the &lt;html> tag and the &lt;body> tag
* Metadata describes how to interpret and format the HTML document stored within the &lt;body> tag

<<ext "W3Schools Head tag">>

!! Sample code

```
<head>
  <title>UrTitle</title>
</head>
```

HTML CSS\Hide content

!! Hide content until user action

* CSS style name = `display`
* value = `none`
* Note: The entire tag and sub-tag structure is hidden
* Note: To hide the root tag and show a child tag, use CSS styles `visibility: hidden` and `visibility: visible`, though the parent markup will still take up screen real estate

<<ext "StackOverflow Hide Parent Show Child tag">>

HTML CSS\HTTP-EQUIV Document Type

!! Simulate an HTTP Respsonse header

* The http-equiv attribute value `content-type` provides an HTTP header specifying that the character encoding for the document is in the content attribute

<<ext "W3Schools Meta HTTP-EQUIV">>

!! Sample code

```
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
```

HTML CSS\iFrame to Local HTML file

```
<iframe src="UrPath\UrFile.html" scrolling=yes style="border-style:none;height:75%;width:100%" ></iframe>

HTML CSS\Language attribute on tags

!! Allow screen-reader to identify the page's default language and / or accent

* tag name = any
* `lang` attr = an ISO-639 Language code
* The official W3C recommendation is to declare the primary language for each Web page with a &lt;...lang => attribute in the &lt;html> tag
* Note: The LANG tag (i.e. the lang="" attribute) is designed to signal screen readers pronunciation engines to switch to another language or accent

<<ext "PSU.edu LangTag">>

!! Sample code

```
<html lang="en-GB">
```

HTML CSS\META Tag names

!! Identify tool or program used to create the website

* tag name = `META`
* `name` attr = `generator`
* `content` attr = The name of the program you used to create your website
* Note: This tag is automatically inserted by website-generating applications
* Note :People who don’t want to advertise which tool or program they used to create the website can remove this tag from the generated pages

<<ext "MetaTags.org Generator">>

!! Sample code

```
<meta name="generator" content="UrProgramTitle" />
```

!! Identifies the name of the application running in the web page

* tag name = `META`
* name attr = `application-name`
* `content` attr = The application that is dynamically supplying content for the current web page
* Note: isolated web pages shouldn't define an application-name

<<ext "Mozilla.org META tags">>

```
<meta name="application-name" content="UrApplicationTitle" />
```

!! Supply hints about the size of the initial size of the viewport

* tag name = `META`
* `name` attr = viewport'
* `content` attr = comma-separated list of equates
* Note: This is used by mobile devices only
* Note: The default values may vary between devices and browsers
* Note: Disabling zooming capabilities by setting user-scalable to a value of no prevents people experiencing low vision conditions from being able to read and understand page content

<<<
* width = ( A positive integer number ) or ( the text `device-width` )
* height = ( A positive integer) or ( the text `device-height` )
* initial-scale = A positive number between 0.0 and 10.0
* maximum-scale = A positive number between 0.0 and 10.0
* minimum-scale = A positive number between 0.0 and 10.0
* user-scalable = `yes`, `no`
* viewport-fit = `auto', 'contain`, `cover`
<<<

<<ext "Mozilla.org META tags">>

!! Sample code

```
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
```

!! Include developer or company information in document

* tag name = `meta`
* `name` attr = `copyright`, `ur_app_name-version`
* `content` attr = Any text data
* Note: This information is not used by the browser

HTML CSS\Meta Tag Schema

<<ext "W3.org HTML401 Meta">>

This specification does not define a set of legal meta data properties.
The meaning of a property and the set of legal values for that property should be defined in a reference lexicon called a profile.

<<ext "W3.org HTML401 Profiles">>

The profile attribute of the HEAD specifies the location of a meta data profile.
The value of the profile attribute is a URI.
User agents may use this URI in two ways:

* As a globally unique name.

<<<
User agents may be able to recognize the name (without actually retrieving the profile) and perform some activity based on known conventions for that profile.
For instance, search engines could provide an interface for searching through catalogs of HTML documents, where these documents all use the same profile for representing catalog entries.
<<<

* As a link.

<<<
User agents may dereference the URI and perform some activity based on the actual definitions within the profile (e.g., authorize the usage of the profile within the current HTML document).
This specification does not define formats for profiles.
<<<


HTML CSS\Noscript alternate content

!! Add content when viewed with JavaScript-disabled browsers

* tag name = `noscript`
* Note: The tag contents are displayed to users that have disabled scripts in their browser or have a browser that doesn't support user action event scripting

<<ext "W3Schools NoScript tag">>

!! Sample code

```
</noscript>
<!--Javascript-disabled browser additional content-->
</noscript>
<!--Ordinary content-->
```

HTML CSS\Padding and Margin

```
style="margin-left:30px"

style="padding-left:10px"

HTML CSS\Table Rows Alternate

Stylesheet classes:

```
.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}
```

HTML using class

```
<table class="alternating-rows">
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

HTML CSS\Website icon

!! Show an icon next to the Website Name

* tag name = `link`
* `rel` attr = `icon`, `shortcut icon`
* `href` attr = Website icon filename, relative path, or full path
* Note: The favicon is loaded as soon as the browsers parses the link rel="icon" declaration, or after the page is loaded when the link is not found
* Note: The icon keyword may be preceded by the keyword "shortcut". If the "shortcut" keyword is present, the rel attribute's entire value must be an ASCII case-insensitive match for the string "shortcut icon" (with a single U+0020 SPACE character between the tokens and no other ASCII whitespace).

<<ext "MathiasBynens Rel Icon">>

<<ext "WHATWg.org Link Icon">>

!! Sample code

```
<link rel="shortcut icon" href="favicon.ico">
```

Instapaper

<<glbl_article_list>>

Instapaper\Export as CSV

"""
[https://www.instapaper.com/u]
- [Top-right icon]
- Click login-name menu, option Settings -> Navigates page
- [Settings page, Export section]
- Click link Download .CSV file -> Opens dialog
- Click button OK -> Starts download, closes dialog

[CSV file]
- Header fields =
"""

```
URL
Title
Selection
Folder
Timestamp
```

- Header line =

```
URL,Title,Selection,Folder,Timestamp
```

- Sample data 1 =

```
https://m.youtube.com/watch?v=ABC123DEF&index=14,"""UrQuotedText"" - UrVideoTitle",UrCommentText,"UrInstapaperFolder",1605840648
```

- Sample data 1 =

```
https://www.urcompany.com/urfolder/urarticle/,UrArticleTitle,,UrInstapaperFolder,UrCommentText1603883475
```

Instapaper\Parse file

```
\define link_title()
''[<$list filter="[<http_text>split[,]butlast[]last[]]" />]'' <$list filter="[<http_text>split[,]rest[]first[]]" />
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]floor[]]"><$vars tid_year=<<currentTiddler>> >
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]subtract<tid_year>multiply[12]floor[]]"><$vars tid_month=<<currentTiddler>> >
(<<tid_year>>-<<tid_month>>)
</$vars></$list>
</$vars></$list>
<ul>
<$list filter='[<http_text>split[,]butlast[]butlast[]butfirst[]butfirst[]join[,]split["]butfirst[]butlast[]join["]split[""]join["]split[...]]'>
<li><<currentTiddler>></li>
</$list>
</ul>
\end
<$list filter="[{WebNotes\Data}split[http]count[]]" ><$vars total_count=<<currentTiddler>> >Count of entries: <<total_count>><br><br>
<!--
<$button>
<$action-setfield $tiddler="$:/state/popup/audit_1k" text="0"/>
Reset
</$button><br>

<$button>
<$list filter="[{$:/state/popup/audit_1k}add[1000]]">
<$action-setfield $tiddler="$:/state/popup/audit_1k" text=<<currentTiddler>> />
Next 1k
</$list>
</$button><br>
{{$:/state/popup/audit_1k}}

<$list filter="[{WebNotes\Data}split[http]first{$:/state/popup/audit_1k}last[1000]]"><$vars http_text=<<currentTiddler>> >
-->
<$list filter="[{WebNotes\Data}split[{{]join[-opencurlybrace-]split[http]]"><$vars http_text=<<currentTiddler>> >
<$list filter="[<http_text>split[,]first[]!suffix[URL]addprefix[http]]"><$vars http_link=<<currentTiddler>> >
<$list filter="[all[tiddlers]field:twnote<currentTiddler>count[]match[0]]">
<<http_link>><br>
- <<link_title>> <br>
</$list>
</$vars></$list>
</$vars></$list>
</$vars></$list>
```

IrfanView

<<glbl_article_list>>

IrfanView\Contact Sheet

"""
[IrfanView app]
- Open one thumbnail image -> Loads image
- Click the File menu option Thumbnails -> Opens dialog
- [Thumbnails dialog]
- Select all files in the folder
- Click the File menu, option Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

JavaScript

<<glbl_article_list>>

JavaScript\Comment text

!! Place a comment text block inside of a JavaScript program

* tag name = `script`
* `type` attr = `text/javascript`
* Start JavaScript comment text block with forward-slash asterisk ( `/*` )
* End comment text with asterisk forward-slash ( `*/` )
* Start JavaScript comment text line with two forward-slashes ( `//` )

!! Sample code

```
<style type="text/javascript">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>
```

JavaScript\Execute Nameless Function

```
;(
    function() {
        alert('hi');
        }
    )();

JavaScript\Exports object

!! Determine if running under Node.JS

* Initially at least, `exports` is a reference to `module.exports`
* If you assign anything to `module.exports`, `exports` is not no longer a reference to it, and exports loses all its power

<<ext "SitePoint Exports Node.JS">>

JavaScript\Invalid Variable Names

<<ext "JavaScript Strict Mode">>

Strict mode makes assignments which would otherwise silently fail to throw an exception.  For example, NaN is a non-writable global variable. In normal code assigning to NaN does nothing; the developer receives no failure feedback. In strict mode assigning to NaN throws an exception.

```
'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError
```

Strict mode in ECMAScript 2015 forbids setting properties on primitive values. Without strict mode, setting properties is simply ignored (no-op), with strict mode, however, a TypeError is thrown.

```
(function() {
'use strict';

false.true = '';         // TypeError
(14).sailing = 'home';   // TypeError
'with'.you = 'far away'; // TypeError

})();
```

JavaScript\Labels

The labeled statement can be used with break or continue statements.

```
List: 
while(counter < 50)
{
     userInput += userInput;
     counter++;
     if(userInput > 10000)
     {
          break List;
     }
}
```

```
var i = 100, j = 100;
outerloop:
while(i>0) {
  while(j>0) {
   j++

   if(j>50) {
     break outerloop;
   }
  }
i++

}
```

```
loop1:
for (let i = 0; i < 5; i++) {
  if (i === 1) {
    continue loop1;
  }
  str = str + i;
}
```

JavaScript\Logical And/Or

If a value can be converted to true, the value is so-called truthy. If a value can be converted to false, the value is so-called falsy.

Examples of expressions that can be converted to false are:

* null
* NaN
* 0
* empty string ( ` "" ` or ` '' ` ) or empty template literal ( &#x0060;&#x0060; )
* undefined

The logical OR expression is evaluated left to right, and first truthy returned expression stops evaluation of the remaining expressions

The && operator is executed before the || operator

Note: If you use this operator to provide a default value to some variable, be aware that any falsy value will not be used. If you only need to filter out null or undefined, consider using the nullish coalescing operator ( ` ?? ` )

JavaScript\Multi-line string

It's not a multiline string, it's a one line string split over multiple lines of code that make up a single statement.

Old version uses backslash as a line continuation character:

```
eval(" \
alert('hi'); \
");
```

New version uses backtick character as multi-line string:

WARNING: Not supported by IE

```
eval(`
alert('hi');
`);
```

Use string concatenation instead:

```
eval(
"var v1 = 'hi';" +
"alert(v1);"
);
```


JavaScript\Run in HTML Document

```
<html>
  <body><script type = "text/javascript">window.onerror=function(msg,url,line){alert("Line number = "+line+"\nMessage:\n\n"+msg)}</script>
    <script type="text/javascript">
alert('hi';
      </script>
    </body>
  </html>

JavaScript\Strict Mode

!! Show strict mode compilation errors on specific scripts or functions

* First statement in script or function: 'use strict'; or "use strict";
* Note: Strict mode applies to entire scripts or to individual functions, not individual block statements enclosed in {} braces within a function
* Note: Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally
* Note: The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it

<<ext "MozillaDeveloper Strict mode">>

!! Sample data

```
"use strict";
mistypeVariable = 17;
```

<<<
Result in Developer Tools, Javascript Console:

```
Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLineNumber
```
<<<

```
<script type="module">
mistypeVariable = 17;
</script>
```

<<<
Result:

```
Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLine
```
<<<

JavaScript\String Escape Codes

"""
Here are all the string escape codes:

\0 The NUL character (\u0000)
\b Backspace (\u0008)
\t Horizontal tab (\u0009)
\n Newline (\u000A)
\v Vertical tab (\u000B)
\f Form feed (\u000C)
\r Carriage return (\u000D)
\" Double quote (\u0022)
\' Apostrophe or single quote (\u0027)
\\ Backslash (\u005C)
\x XX The Latin-1 character specified by the two hexadecimal digits XX
\u XXXX The Unicode character specified by the four hexadecimal digits XXXX

JavaScript\This object

<<ext "JavaScript This Parameter">>

Functions called via property references get "this" set for them: This is the part that really makes it seem like JavaScript has methods: The "this" reference gets set automagically to the object instance if you call a function via a property reference.

Within that call, use the object in question as "this". Getting the function reference from an object property doesn't link it in any way to the object the property came from. The JavaScript engine treats calls of functions just retrieved from object properties as special and sets up "this" accordingly. Essentially, "this" is just a function argument that's passed into the function as an implicit feature of calling a function via a property reference.

JavaScript gives us the call and apply methods on function instances, with which we can say explicitly what we want "this" to be. If you say myfunction.call(myobject), you're saying "call myfunction and use myobject as 'this'", which is what the property-retrieval stuff does implicitly for you.

`UrObject.UrFunction();`

- equates to -

`UrObject.UrFunction.call(UrObject);`

Everything can be seen as a function.

`window['UrObject']['UrFunction'].call(window['UrObject']);`

Getting the function reference from the property (UrObject.UrFunction) is distinct from the fact we're calling it (call) is distinct from what "this" should be ((UrObject)).

<<ext "JavaScript Closures">>

The interpreter creates a call object for this particular execution of the function and sets some properties on that call object before passing it into the function's code.

* A property called arguments which is an array (of sorts, in most implementations it's not actually an Array object) of the actual arguments we called the function with, plus a callee property which is a reference to the function being called.
* A property for each of the arguments defined by the function declaration. The values of these properties are set to the values passed into the function. If any arguments weren't specified (because JavaScript lets you call functions with however many arguments you want, regardless of the definition), properties for any missing arguments are still created on the call object — with the value undefined.
* A property for every declared variable within the function (e.g., every "var" statement). (These start out with the value undefined.)

```
window.UrFunction(UrObject1, UrObject2);
```

That creates a call object for this execution of updateDisplay that essentially looks like this:

```
call.arguments = [UrObject1, UrObject2]
call.arguments.callee = UrFunction
call.ur_input_parm1 = UrObject1
call.ur_input_parm2 = UrObject2
call.internal_var1 = undefined
```

The use of the call object is implicit, because once the call object is created, it's put at the top of the scope chain for the duration of the function call.

JavaScript\TypeOf Name

!! Get string representing object type

* typeof always returns a string
* Note: typeof operator takes precedence over string concatenation ( ` + ` )
* Note: type a let or const variable in a block before they are declared will throw a ReferenceError

* Undefined, undeclared variable, or unassigned variable = "undefined"
* Boolean(1), !!(1) = "boolean"
* Number('321') , Infinity, NaN = "number"
* Bigint, 321n = "bigint"
* String = "string"
* Symbol = "symbol"
* Function() {}, class UrClassName {},  = "function"
* null, object, {ur_prop_name: ur_prop_value}, [ur_val1, ur_val2, ur_val3], new Date(), /regex/ = "object"

JavaScriptBookmarklets

<<glbl_article_list>>

JavaScriptBookmarklets\Bibliographic citation

<<ext "ALAorg Citations bookmarklet">>
```
javascript:(function(){var h=document.createElement('div');var t=document.getElementsByTagName('title')[0];var info='<p><strong>Title('+t.innerHTML.length+'):</strong> '+t.innerHTML+'</p>';var m=document.getElementsByTagName('meta');for(var i=0;i < m.length;i++){if(null !==m[i].getAttribute('name')){var c=m[i].getAttribute('content');info+='<p><strong>'+m[i].getAttribute('name')+'('+c.length+'):</strong> '+c+'</p>';}}var lm=document.lastModified;var url=location.href;var d=new Date();var dd=d.getDate();var mm=d.getMonth()+1;var yyyy=d.getFullYear();info+='<p><strong>Citation: </strong>"' + t.innerHTML + '." Last modified '+lm+'. <a target="_blank" href="'+url+'">'+url+'</a> (accessed '+mm+'/'+dd+'/'+yyyy+').</p>';document.body.insertBefore(h,document.body.firstChild);h.innerHTML='<div style="border:1px solid %23888;border-radius:5px;-moz-box-shadow:0 0 5px %23888;-webkit-box-shadow:0 0 5px%23888;box-shadow:0 0 5px %23888;background:%23eee;text-align:left;padding:1em;"><a href="%23" onclick="document.body.removeChild(document.body.firstChild);return false">remove</a>'+info+'</div>';})();

JavaScriptBookmarklets\Clear all CSS

Clears all the CSS Class and Style attributes

```
avascript:(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["module"], factory);
  } else if (typeof exports !== "undefined") {
    factory(module);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod);
    global.clearAllCSS = mod.exports;
  }
})(this, function (module) {
  "use strict";

  var each = Array.prototype.forEach;


  function clearAllCSS(nest_level, cur_elt) {
    var _context2;
    if (!cur_elt) {
        throw new Error("No element specified.");
        }

    var _context;
    (_context = cur_elt.children, each).call(_context, function (child) {
        clearAllCSS(nest_level+1, child);
        });

    while(cur_elt.attributes.length > 0) {
        cur_elt.removeAttribute(cur_elt.attributes[0].name);
        }
    }

  module.exports = clearAllCSS;
});
document.querySelectorAll('iframe,script,noscript').forEach(function(element){if (element!=null){element.parentNode.removeChild(element)}});
clearAllCSS(1, document.body);
if (document.head!=null){document.head.parentNode.removeChild(document.head)};
document.querySelectorAll('link').forEach(function(element){if (element!=null){element.parentNode.removeChild(element)}});
document.body.style.fontSize=prompt("Please enter font multiplier", "2") + "00%";
undefined;

JavaScriptBookmarklets\Convert to Inline CSS

Run this script (it takes a while) and then save the web page. All the CSS properties are specified on each element, so it does not need to load any stylesheets.

<<ext "GitHub LukeHorvat Computed Style to Inline">>

```
avascript:(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["module"], factory);
  } else if (typeof exports !== "undefined") {
    factory(module);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod);
    global.computedStyleToInlineStyle = mod.exports;
  }
})(this, function (module) {
  "use strict";

  var each = Array.prototype.forEach;


  function computedStyleToInlineStyle(nest_level, parent_style, cur_elt) {
    var _context2;
    if (!cur_elt) {
        throw new Error("No element specified.");
        }

    var cur_style = getComputedStyle(cur_elt);
    var _context;
    (_context = cur_elt.children, each).call(_context, function (child) {
        computedStyleToInlineStyle(nest_level+1, cur_style, child);
        });

    var parent_copy = document.createElement("an_unknown_tag");
    if (nest_level > 1) {
        for (var pctr = 0; pctr < parent_style.length; pctr++) {
            var pname = parent_style[pctr];
            var pval = parent_style.getPropertyValue(pname);
            parent_copy.style[pname] = pval;
            }
        }

    var blank_element = document.createElement("an_unknown_tag");
    parent_copy.appendChild(blank_element);
    document.head.appendChild(parent_copy);
    var blank_style = getComputedStyle(blank_element);

    for (var dctr = 0; dctr < blank_style.length; dctr++) {
        if (dctr < cur_style.length) {
            var dname = blank_style[dctr];
            var dval = blank_style.getPropertyValue(dname);
			var cval = cur_style.getPropertyValue(dname);
            if (cval != dval && cur_elt.style[dname] != dval) {
                cur_elt.style[dname] = cval;
                }
            }
        }
    }

  module.exports = computedStyleToInlineStyle;
});
(function(){
	var h = document.createElement('div');
	var t = document.getElementsByTagName('title')[0];
	var cite_remove = '<a href="%23" onclick="document.body.firstChild.style.visibility = \'hidden\';document.body.firstChild.style.height = \'0px\';return false">remove</a>';
	var info = '<p><strong>Title(' + t.innerHTML.length + '):</strong> ' + t.innerHTML + '</p>';
	var m = document.getElementsByTagName('meta');
	for(var i = 0; i < ((m == null) ? 0 : m.length); i++) {
		if(null !== m[i].getAttribute('name') ) {
			var c=m[i].getAttribute('content');
			if (c != null) {info += '<p><strong>' + m[i].getAttribute('name') + '(' + c.length + '):</strong> ' + c + '</p>';}
			}
		}
	
	var lm = document.lastModified;
	var url = location.href;
	var d = new Date();
	var dd = d.getDate();
	var mm = d.getMonth()+1;
	var yyyy = d.getFullYear();
	info += '<p><strong>Citation: </strong>"' + t.innerHTML + '." Last modified ' + lm + '. <a target="_blank" href="' + url + '">' + url + '</a> (accessed ' + mm + '/' + dd + '/' + yyyy + ').</p><p><strong>Filename:</strong> ' + '0'.repeat(4-yyyy.toString().length) + yyyy + 'm'+'0'.repeat(2-mm.toString().length) + mm + 'd' + '0'.repeat(2-dd.toString().length) + dd + ' ' + url.replace('http://','').replace('https://','').replace('file:///','').replaceAll('/','-fslash-') + '.html</p>';
	document.body.insertBefore(h,document.body.firstChild);
	h.innerHTML='<div style="border:1px solid %23888;border-radius:5px;-moz-box-shadow:0 0 5px %23888;-webkit-box-shadow:0 0 5px%23888;box-shadow:0 0 5px %23888;background:%23eee;text-align:left;padding:1em;">' + cite_remove + info + cite_remove + '</div>';
	})();
document.querySelectorAll('iframe,script,noscript').forEach(function(element){element.parentNode.removeChild(element)});
computedStyleToInlineStyle(1, null, document.body);
document.head.parentNode.removeChild(document.head);
document.querySelectorAll('link').forEach(function(element){element.parentNode.removeChild(element)});
alert("done");

JavaScriptBookmarklets\Edit current page

Edit webpage

```
javascript:document.body.contentEditable = 'true'; document.designMode='on'; void 0
```

Editing Done

```
javascript:document.body.contentEditable = 'false'; document.designMode='off'; void 0
```

JavaScriptBookmarklets\Extract iFrame pages

```
(function(){ var imgs = document.getElementsByTagName('iframe'),t=[]; for (var i=0, n=imgs.length;i'+ imgs[i].src+''); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract images

```
avascript:(function(){ var imgs = document.getElementsByTagName('img'),t=[]; for (var i=0, n=imgs.length;i<n;i++) t.push('<a href="'+imgs[i].src+'"><img src="'+ imgs[i].src+'" width="100"></a>'); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract plain text

Copy the HTML body to a new window, so CSS and Javascript are ignored

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML;void(newWindow.focus());}
```

Copy the HTML body to a new window showing the HTML tags, so you can see the HTML code

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/&/g,"&amp;").replace(/</g,"<br>&lt;");void(newWindow.focus());}
```

Copy the HTML body without any HTML tags, so the text is loaded without any HTML or CSS styling

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/<[^>]+>/g, '<br>');void(newWindow.focus());}
```

JavaScriptBookmarklets\Unescape HTML code

```
avascript:document.documentElement.innerHTML='<html><body>'+document.body.innerHTML.replaceAll('&lt;','<').replaceAll('&gt;','>').replaceAll('&amp;','&')+'<\/body><\/html>';

JavaScriptBookmarklets\View HTML Source

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){;newWindow.document.documentElement.innerHTML='<html><head><title>Source of Page<\/title><\/head><body><pre>'+document.documentElement.outerHTML.replaceAll('&','&amp;').replaceAll('<','&lt;')+'<\/pre><\/body><\/html>';newWindow.document.body.contentEditable = 'true'; newWindow.document.designMode='on';void(newWindow.focus());}

JavaScriptBookmarklets\View HTML to TW

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){;newWindow.document.documentElement.innerHTML='<html><head><title>Source of Page<\/title><\/head><body><pre>'+document.documentElement.outerHTML.replaceAll('&','&amp;').replaceAll('<','&lt;').replaceAll('&lt;html','&lt;div').replaceAll('&lt;\/html','&lt;\/div').replaceAll('&lt;body','&lt;div').replaceAll('&lt;\/body','&lt;\/div').replaceAll('position: absolute','position: relative').replaceAll('position: fixed','position: relative').replaceAll('position: flex','position: relative').replaceAll('>remove&lt;\/a>','&gt;&lt\/a&gt;').replaceAll('src="http','src_attr="http').replaceAll('src=\'http','src_attr=\'http')+'<\/pre><\/body><\/html>';newWindow.document.body.contentEditable = 'true'; newWindow.document.designMode='on';void(newWindow.focus());}

keyboard action FontLarge

<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/fontsize" text="24px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/lineheight" text="30px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize" text="25px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodylineheight" text="34px"/>

keyboard action FontNormal

<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/fontsize" text="14px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/lineheight" text="20px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize" text="15px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodylineheight" text="24px"/>

keyboard action HomeTiddlers

<$action-sendmessage $message="tm-home"/>

keyboard action Preview

<$list filter="[[$:/state/showeditpreview]get[text]!match[yes]]"><$action-setfield $tiddler="$:/state/showeditpreview" text="yes"/></$list>
<$list filter="[[$:/state/showeditpreview]get[text]match[yes]]"><$action-setfield $tiddler="$:/state/showeditpreview" text="no"/></$list>


keyboard action SaveAllChanges

\define ExportSaveAll(ur_filename, ur_stamp, ur_save_wiki_extension, ur_save_export_html)
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" filename="WikiMove_$ur_filename$-stamp-$ur_stamp$$ur_save_wiki_extension$"
/>
<$list variable=save_export_html filter="[[$ur_save_export_html$]match[1]]">
<$list variable=save_as_html_path filter="[[$ur_filename$]split[-fslash-src-fslash-]join[-fslash-]addprefix[WikiMove_]addsuffix[-stamp-$ur_stamp$.html]]">
<$action-sendmessage $message="tm-download-file"
$param="$:/core/templates/exporters/StaticRiver" filename=<<save_as_html_path>>
exportFilter="""[all[tiddlers]tag[INDEX]sort[title]][all[tiddlers]!tag[EXT]!tag[INDEX]!tag[META]!tag[MCR]!prefix[Draft of]!is[image]!is[tag]!is[system]sort[title]]"""/>
</$list><!--save_as_html_path-->
</$list><!--save_export_html-->
<$action-sendmessage $message="tm-download-file"
$param="template ExportAllCode" filename="WikiMove_$ur_filename$-stamp-$ur_stamp$.card.txt" />
\end
<$list variable=save_export_html filter="[{$:/info/url/full}suffix[.htm]count[]] [[parm SkipSaveExportHTML]is[tiddler]count[]multiply[-1]] +[sum[]]">
<$list variable=save_wiki_extension filter="[{$:/info/url/full}split[.]last[]addprefix[.]]">
<$list variable=save_as_file_name filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.html]join[]split[.htm]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<save_as_file_name>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> ur_save_wiki_extension=<<save_wiki_extension>> ur_save_export_html=<<save_export_html>> />
</$list><!--save_as_file_name-->
</$list><!--save_wiki_extension-->
</$list><!--save_export_html-->

mcr glbl_article_list

\define glbl_article_list()
<ol>
<$list variable=card_prefix filter="[<currentTiddler>addsuffix[\]]">
<$list variable=cur_card filter="[prefix<card_prefix>sort[]]">
<$list variable=disp_name filter="[<cur_card>split[\]butfirst[]join[\]]">
<li><$link to=<<cur_card>> ><<disp_name>></$link></li>
</$list><!--disp_name-->
</$list><!--cur_card-->
</$list><!--card_prefix-->
</ol>
\end
\define glbl_article_checklist()
<$vars cur_card=<<currentTiddler>> >
<<glbl_dt_ddd>>
<$wikify name=cur_date text="""<<now "YYYYm0MMd0DD">>""" >
<$list variable=diff_date filter="[<cur_card>get[match_date]else[]!match<cur_date>]">
<$button>
<$list variable=field_name filter="[<cur_card>fields[]prefix[chk_]]">
<$action-setfield $field=<<field_name>> $value="" />
</$list><!--field_name-->
<$action-setfield match_date=<<cur_date>> />
Clear all checkmarks
</$button>
</$list><!--diff_date-->
</$wikify><!--cur_date-->
<ol>
<$list variable=card_prefix filter="[<cur_card>addsuffix[\]]">
<$list variable=cur_entry filter="[prefix<card_prefix>sort[]]">
<$list variable=disp_name filter="[<cur_entry>split[\]last[]]">
<$list variable=chk_name filter="[<disp_name>addprefix[chk_]split[ ]join[_]lowercase[]]">
<li>
<$checkbox default="no" unchecked="no" checked="yes" tiddler=<<cur_card>> field=<<chk_name>> >
<$link to=<<cur_entry>> ><<disp_name>></$link>
</$checkbox>
</li>
</$list><!--chk_name-->
</$list><!--disp_name-->
</$list><!--cur_card-->
</$list><!--card_prefix-->
</ol>
</$vars>
\end

mcr glbl_code_split

\define glbl_code_block(ur_note_pk)
[[$ur_note_pk$]]
<$codeblock code={{$ur_note_pk$}} />
\end
\define glbl_code_linenum(ur_note_pk, ur_skip_count, ur_section_size, ur_disp_linenum)
<div style="clear:both">[[$ur_note_pk$]]</div>
<$list filter="[[$ur_skip_count$]!match[]else[0]]" variable=intSKIP_COUNT>
<$list filter="[[$ur_note_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>count[]]" variable=intLINE_COUNT>
<$list filter="[[$ur_section_size$]!match[]!match[0]else<intLINE_COUNT>]" variable=intSECTION_SIZE>
<$list filter="[range<intSECTION_SIZE>]" variable=intCUR_LINE>
<$list filter="[<intCUR_LINE>subtract[1]]" variable=IntREMOVE_LINE>
<$list filter="[[$ur_note_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>butfirst<IntREMOVE_LINE>first[]]" variable=strCUR_LINE>
<$list filter="[[$ur_disp_linenum$]!match[n]!match[0]]"><div style="float:left"><<intCUR_LINE>></div></$list>
<$codeblock code=<<strCUR_LINE>> />
</$list></$list></$list></$list></$list></$list>
\end
\define glbl_code_split_group(ur_note_pk, ur_skip_count)
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]splitregexp[\u0009]join[__	__]splitregexp[\u0020]join[__ __]splitregexp[\u0022\u0022\u0022]join[&#x0022;&#x0022;&#x0022;]]"><<currentTiddler>>
</$list></$list>
\end
\define glbl_code_split_count(ur_note_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_split_group ur_note_pk="$ur_note_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_split_data()
<$macrocall $name=glbl_code_split_count ur_note_pk=<<source_note_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_split_next_group_disp(ur_rem_counter)
<$list filter="[{$ur_rem_counter$}subtract[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_split_disp(ur_source_note_pk, ur_temp_note_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_note_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to find: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
Source data: [[$ur_source_note_pk$]]<br>
\end
\define glbl_code_split_combine()
$(currentTiddler)$$(str_html_out)$
\end
\define glbl_code_split_init(ur_note_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_note_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]add[1]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_note_pk>> text="" />
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_split(ur_note_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_split_init ur_note_pk="$ur_note_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_note_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_split_disp ur_source_note_pk=<<source_note_pk>> ur_temp_note_pk=<<temp_note_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$wikify name=str_html_out text=<<glbl_code_split_data>> >
        <$list filter="[<temp_note_pk>get[text]else[]]"><$vars combine_html_out=<<glbl_code_split_combine>> >
        <$action-setfield $tiddler=<<temp_note_pk>> text=<<combine_html_out>> />
         </$vars></$list>
        <$macrocall $name=glbl_code_split_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> />
        </$wikify>
      
      Find next 100 lines
      </$button><br>

    <$edit-text tiddler=<<temp_note_pk>> autoHeight=no />
    </$vars>
  </$list>
\end
\define glbl_code_disp_group(ur_note_pk, ur_skip_count)
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u00A0]join[&nbsp;]splitregexp[\u0009]join[&nbsp;&nbsp;&nbsp;&nbsp;]splitregexp[\u0020]join[&nbsp;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]]"><<currentTiddler>><br></$list></$list>
\end
\define glbl_code_disp_count(ur_note_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_note_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_disp_data()
<$macrocall $name=glbl_code_disp_count ur_note_pk=<<source_note_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_disp_next_group_disp(ur_rem_counter, ur_oper)
<$list filter="[{$ur_rem_counter$}$ur_oper$[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_disp_disp(ur_source_note_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_note_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to browse: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
\end
\define glbl_code_disp_init(ur_note_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_disp(ur_note_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_disp_init ur_note_pk="$ur_note_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
[[$ur_note_pk$]]<br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_disp_disp ur_source_note_pk=<<source_note_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="subtract" />
      
      Browse next 100 lines
      </$button><br>
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="add" />
      
      Browse prev 100 lines
      </$button><br>

    <<glbl_code_disp_data>>
    </$vars>
  </$list>
\end

<!--<$macrocall $name=glbl_code_disp ur_note_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_disp "WebNotes\Data 1 >>-->

<!--Does not pass through the \u0009 tab or \u00A0 non-breaking space characters. Chrome highlight and copy puts spaces on the clipboard.-->

<!--[[WebNotes\Data]]-->

<!--<$macrocall $name=glbl_code_split ur_note_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_block "UrNotePK">>-->

<!--<<glbl_code_linenum "UrNotePK" 0 15 n>>-->

mcr glbl_compare_lines

\define glbl_compare_lines_results_table(ur_note_pk, ur_second_pk, ur_row_count)
<table><tr>
<th>''Line''</th>
<th>Show text</th>
<th>First Side<br>Second Side</th>
</tr>
<$list filter="[range<intSECOND_COUNT>subtract[1]]" variable="intCUR_ENTRY">
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]]" variable="strFIRST_LINE">
<$list filter="[{$ur_second_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]!match<strFIRST_LINE>]" variable="strSECOND_LINE">
<tr>
<td rowspan=2>

!!<<intCUR_ENTRY>>
</td>
<td>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/CompareTextSection1" text="""<$edit-text tiddler="$:/state/CompareTextLine1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/CompareTextLine1}!match[]else[0]]" variable=intSTART_LINE><$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_note_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_note_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/CompareTextSection1"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strFIRST_LINE>> /></td>
</tr>
<tr>
<td>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/CompareTextSection2" text="""<$edit-text tiddler="$:/state/CompareTextLine2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/CompareTextLine2}!match[]else[0]]" variable=intSTART_LINE>
<$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_second_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_second_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/CompareTextSection2"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strSECOND_LINE>> /></td>
</tr>
</$list></$list></$list>
</table>
\end
\define glbl_compare_lines(ur_note_pk, ur_second_pk)
<$list filter="[{$ur_note_pk$}splitregexp[\n]count[]]" variable="intFIRST_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]]" variable="intSECOND_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]subtract<intFIRST_COUNT>]" variable="intSECOND_EXTRA">

[[$ur_note_pk$]] line count: <<intFIRST_COUNT>>

[[$ur_second_pk$]] line count: <<intSECOND_COUNT>>

''$ur_second_pk$'' excess line count: ''<<intSECOND_EXTRA>>''

<$macrocall $name=glbl_compare_lines_results_table ur_note_pk="$ur_note_pk$" ur_second_pk="$ur_second_pk$" ur_row_count=<<intSECOND_COUNT>> />
</$list>
</$list>
</$list>
\end

<!--
<$edit-text tiddler="$:/state/CompareText1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>
<$edit-text tiddler="$:/state/CompareText2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>

<<glbl_compare_lines "$:/state/CompareText1" "$:/state/CompareText2">>
-->

mcr glbl_dt_ddd

\define glbl_dt_ddd()
<div style="clear:right;float:right;background-color:aquamarine;"><<now "YYYYm0MMd0DD DDD pm0hh12\m0mm">></div>
<$list filter="[<currentTiddler>split[Draft of ']join[]split[ ]first[]split[m]join[]split[d]join[]]">
<$view field="title" format="date" template="[UTC]DDD" />
</$list>
\end

mcr glbl_ext

\define ext(ur_extnote_pk)
<$list variable=missing_entry filter="[[ext $ur_extnote_pk$]get[text]else[]match[]]">Missing: [$ur_extnote_pk$]
</$list><!--missing_entry-->
<$list variable=prefix_dir filter="[{$:/info/url/full}split[/src/]count[]match[2]then[../]else[]]">
<$list variable=found_entry filter="[[ext $ur_extnote_pk$]get[text]else[]addprefix<prefix_dir>]">
<a target="_blank" href=<<found_entry>> >$ur_extnote_pk$</a><div style="float:right">[[->|ext $ur_extnote_pk$]]</div>
</$list><!--found_entry-->
</$list><!--prefix_dir-->
\end

MicrosoftRemoteDesktop

<<glbl_article_list>>

MicrosoftRemoteDesktop\Setup PC

<<ext "Microsoft RemoteDesktop Enable">>

Panel

* https://github.com/settings/tokens
>* If there is an existing personal access token,
>>* Click on the name -> Navigates page
>>* Click button Regenerate Token -> Navigates page
>>* Click button Copy to Clipboard
>* Otherwise create a new token
* https://github.com/settings/tokens/new
>* Note = name of end user and device
>>* Must be unique
>>* Each device should get a different token
>* checkbox "repo" = set
>* Click button Generate token -> Navigates page
>* Click button Copy to Clipboard
!!
* <$link to="$:/ControlPanel" />
>* [Saving tab, GitHub Saver sub-tab]
>* Paste into field "Password, OAUTH token, or personal access token"
>* Close the Control Panel card
!!
* Click button <$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" />
Save Wiki
</$button>
>* Wait a few seconds for the "Saved wiki" notification
>* The token is saved in internal browser storage
>* If you get a "401" error, go back to step 1 to generate a new token

Recent Entries

[[Search All Fields]]

[[Tags Count Audit]]

[[View All Cards]]

[[View All Code]]

[[Font Size]]

<<timeline limit:30 format:"YYYY-0MM-0DD">>

Regular Expressions

<<glbl_article_list>>

Regular Expressions\Explanation

\define disp_re(ur_list, ur_re)
<$vars re="$ur_re$">
`$ur_list$` matches `$ur_re$`?
<$list variable=ret filter="[[$ur_list$]regexp<re>else[no]]"> -,/<<ret>>\,- </$list>

`$ur_list$` split out `$ur_re$`?
<$list variable=ret filter="[[$ur_list$]splitregexp<re>]"> -,/<<ret>>\,- </$list></$vars>
<!--
disp_re-->
\end
[[TiddlyWiki\Regular Expression]]

<<ext "Regexp Filter with brackets">>

<<<
The code would get complexer ^^[sic]^^ too as "[''''[...]'''']" can't be put directly in the regex in TW. You'd have to do it through a variable. And since "[character class]" is reserved in regex you'd also have to escape square brackets "[\[\]]".
<<<

<<ext "Regular Expression Quantifiers">>

Regular expressions take a string of text, and returns a YES or NO as to whether it matches a character pattern.

You can specify a literal character.

* A letter or series of letters
** <<disp_re "ABC" "B">>
* `\`. is a literal period, because without the \ escape it would have special meaning
** <<disp_re "AA.AA" "\.">>

You can use tokens to specify a kind of character to match.

* `\d` is a numeric digit 0 through 9
** <<disp_re "A2C" "\d">>

* `\D` is any non-numeric digit
** <<disp_re "5A8" "\D">>

* `\s` is a whitespace character; like space, tab, or line feed
** <<disp_re "A C" "\s">>

* `\S` is a non-whitespace character
** <<disp_re "A" "\S">>

* `\W` is a whitespace or punctuation character (non-word character)
** <<disp_re ";" "\W">>

* `\w` is a word character (non-whitespace and non-punctuation character)
** <<disp_re "A" "\w">>

* `.` period is any character
** <<disp_re "A" ".">>

You can get out of having to use the \ escape over a block of text if you prefer to type it out.

* `\QOne. Two. Three.\E`  treats anything between the delimiters as a literal string, like "One. Two. Three."
** Useful to escape metacharacters
** Otherwise the periods would be special characters applied to the one letter before each period
** You can also write it as `One\. Two\. Three\.`

A regex quantifier such as `+` tells the regex engine to match a certain quantity of the character, token or subexpression immediately to its left.

* `A+` the quantifier + applies to A
** <<disp_re "AAABCCC" "B+">>
** <<disp_re "AAABBBCCC" "B+">>
* `A*` the quantifier * applies to A
** <<disp_re "ABBBC" "B*">>
** <<disp_re "AC" "B*">>
* `ABC?` the quantifier `?` applies to the C—not to ABC
** <<disp_re "ABCD" "BC?">>
** <<disp_re "ABD" "BC?">>
* `(?:A|B|C)+` the quantifier + applies to the subexpression
** <<disp_re "ABCD" "(?:B|C)+">>
** <<disp_re "ABD" "(?:B|C)+">>
* `\QA.B.C\E+` is treated as a sequence of literals, so the quantifier only applies to the last character
** This could also be written as `A\.B\.C+`

By default, a quantifier tells the engine to match as many instances of its quantified token or subpattern as possible. This behavior is called greedy.

* `A+` is greedy, and matches all the number characters in a row from the starting point where exists (a number)
** <<disp_re "ABBBCD" "B+">>
* `A+B` is greedy, and matches all the number characters in a row where exists (a letter B after a letter A)
** <<disp_re "ABBBCD" "B+C">>
** <<disp_re "ABBBCD" "(B+)C">>

In contrast to the standard greedy quantifier, which eats up as many instances of the quantified token as possible, a lazy (sometimes called reluctant) quantifier tells the engine to match as few of the quantified tokens as needed.

* `\w*?B` is lazy, and matches as few word characters in a row as needed where exists (a letter B after a word character)
** <<disp_re "+ABCCC+" "\w*?C">>
** <<disp_re "+ABCCC+" "\w*C">>

In contrast to the standard docile quantifier, which gives up characters if needed in order to allow the rest of the pattern to match, a possessive quantifier tells the engine that even if what follows in the pattern fails to match, it will hang on to its characters.

* A++ is possessive—it matches as many characters as needed and never gives any of them back.
** Whereas the regex A+. matches the string AAA, A++. doesn't. At first, the token A++ greedily matches all the A characters in the string. The engine then advances to the next token in the pattern. The dot . fails to match because there are no characters left to match. The engine looks if there is something to backtrack. But A++ is possessive, so it will not give up any characters. There is nothing to backtrack, and the pattern fails. In contrast, with A+., the A+ would have given up the final A, allowing the dot to match.

You can specify a number range of characters to repeat.

* A{2,9} uses two to nine As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
** <<disp_re "+ABCCC+" "C{1,2}">>
** <<disp_re "+ABCCC+" "C{2,2}">>
** <<disp_re "+ABCCC+" "C{2,9}">>
* A{2,} uses two or more As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
** <<disp_re "+ABCCC+" "C{2,}">>

You can use negated character classs to match characters other up to the one you want.

* `^[^\.]*` skips up to first period
** <<disp_re "AB.C.D" "^[^\.]*">>
* `^.*\.` skips up to last period
** <<disp_re "AB.C.D" "^.*\.">>

Tempered Greedy Token Solution

* `A(?:(?!B).)*B` stops at the first B instead of the last B
** <<disp_re "AB.C.DCE" "B(?:(?!C).)*C">>
** <<disp_re "AB.C.DCE" "B.*C">>

* `A(?:(?!C)(?!B).)*B` stops at the first B unless there is a C between the A and B
** <<disp_re "AB.CA" "B(?:(?!D)(?!C).)*C">>
** <<disp_re "AB.CAB.FGHBC" "B(?:(?!D)(?!C).)*C">>
** <<disp_re "AB.CAB.DFGHBC" "B(?:(?!D)(?!C).)*C">>

Search All Fields

<$vars search_text_pk="$:/state/popup/SearchAllFields">
<$list variable=show_code_pk filter="[<search_text_pk>addsuffix[-checkShowCode]]">
<$list variable=skip_system_pk filter="[<search_text_pk>addsuffix[-checkSkipSystem]]">
<$edit-text tiddler=<<search_text_pk>> field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler=<<skip_system_pk>>> Skip System </$checkbox><br>
<br>

<$list variable=cur_search_text filter="[<search_text_pk>get[text]addsuffix[(?i)]!match[]]">
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]else[no]]">
<$list variable=cur_skipsystem_text filter="[<skip_system_pk>get[text]else[yes]match[yes]count[]]">

<!--Card titles-->
<$list variable=cur_pk filter="[regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_skipsystem_text>] [<cur_pk>!is[system]count[]] +[sum[]match[1]]">

<$link to=<<cur_pk>> />: title
</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

<!--Card fields-->
<$list variable=cur_pk filter="[!regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_pk>is[system]count[]multiply<cur_skipsystem_text>match[0]]">
<$list variable=cur_field filter="[<cur_pk>fields[]]">
<$list variable=found_field filter="[<cur_pk>get<cur_field>regexp<cur_search_text>]">

<$link to=<<cur_pk>> />: <<cur_field>>
<$list variable=disp_code filter="[<cur_showcode_text>match[yes]]">
<$codeblock code=<<found_field>> />
</$list><!--disp_code-->
</$list><!--found_field-->
</$list><!--cur_field-->

</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

</$list><!--cur_skipsystem_text-->
</$list><!--cur_showcode_text-->
</$list><!--cur_search_text-->
</$list><!--skip_system_pk-->
</$list><!--show_code_pk-->
</$vars><!--search_text_pk-->

SQLite

<<glbl_article_list>>

SQLite\Blob text

<<ext "SQLite Blob text">>

```
WITH RECURSIVE test(c,cur) as (
     SELECT '', HEX(blob_field) FROM UrTable WHERE UrPK = 6
   UNION ALL
    select c || char((case substr(cur,1,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,1,1) end)*16
               + (case substr(cur,2,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,2,1) end)),
substr(cur,3)
from test where length(cur)>0
)
select * from test
```

SQLite\Database Browser

<<ext "SQLite DB Browser">>

I used `DB Browser for SQLite - .zip (no installer) for 64-bit Windows`

SQLite\Information Schema

<<ext "SQLite schema information">>

```
SELECT name, sql FROM sqlite_master
WHERE type='table'
ORDER BY name;
```

<<ext "SQLite Language functions">>

sqlite_source_id()

```
--version string of SQLite Library source code
2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f
```

sqlite_version()

```
--version string of SQLite Library running
3.33.0
```

SQLite\String Manipulation

<<ext "SQLite Language functions">>

```
--comment
```

CHAR(unicode_char_list)

COALESCE(field_list)

HEX(field)

IFNULL(field, default_text)

INSTR(field, search_text)

LENGTH(field)

LIKE(field, comparison_text)

* field LIKE comparisontext
* LIKE(field, comparison_text, escape_char)

LOWER(field)

LTRIM(field)

* LTRIM(field, chars_to_remove)

PRINTF(format_text, field_list)

REPLACE(field, search_text, new_text)

RTRIM(field)

* RTRIM(field, chars_to_remove)

SUBSTR(field, start_char)

* SUBSTR(field, start_char, char_count)

TRIM(field)

* TRIM(field, chars_to_remove)

typeof(field)

* "null", "integer", "real", "text", or "blob".

UNICODE(number)

UPPER(field)

SQLite\Top or Limit records

<<ext "SQLite Top 5 Records">>

SELECT * FROM Table_Name LIMIT 5;

Tags Count Audit

<$list variable=cur_card filter="[!has[tags]!prefix[$:]]">

<$link to=<<cur_card>> />
</$list><!--cur_card-->

---
<$list variable=cur_card filter="[!tag[DOC]!tag[EXT]!tag[IMG]!tag[INDEX]!tag[META]has[tags]!prefix[$:]]">
<$list variable=filter_tag_count filter="[<cur_card>tags[]butfirst[]first[]count[]match[0]]">

<$link to=<<cur_card>> />
</$list><!--filter_tag_count-->
</$list><!--cur_card-->

template ExportAllCode

\define renderContent()
<$list variable=cur_tip_pk filter="[all[tiddlers]!has[draft.of]!is[image]has[tags]!prefix[undefined]] [!prefix[$]!has[draft.of]!is[image]!has[tags]!prefix[undefined]] +[sort[title]]">
<hr>
<h2><$link to=<<cur_tip_pk>> /></h2>
<$list variable=cur_tip_text filter="[<cur_tip_pk>get[text]]">
<$codeblock code=<<cur_tip_text>> />
</$list><!--cur_tip_text-->
</$list><!--cur_tip_pk-->
\end
<<renderContent>>

template Home Button

<$list variable=on_twcard filter="[<tv-config-toolbar-icons>!match[no]]">
<div style="float:right;padding-left:30px;">
{{$:/core/ui/TopBar/menu}}
</div>

<div style="float:right"><$button set="$:/state/sidebar" setTo="no" tooltip={{$:/language/Buttons/Home/Hint}} aria-label={{$:/language/Buttons/Home/Caption}} class=<<tv-config-toolbar-class>>>
<span class="tc-dirty-indicator">
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/home-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Home/Caption}}/></span>
</$list>
</span>
<$action-sendmessage $message="tm-home"/>
</$button></div>
</$list><!--on_twcard-->

TiddlyWiki

<<glbl_article_list>>

TiddlyWiki\Add Tag to All Cards

```
<$button>
<$action-setfield $tiddler="Test1" tags="COPY"/>
Reset Test1 Card's Tag list with just COPY
</$button>

<$button>
<$list variable=cur_card filter="[is[tiddler]!prefix[$:/state/]]">
<$list variable=has_tag filter="[<cur_card>tags[]count[]!match[0]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[append[COPY]]"/>
</$list>
</$list>
Append COPY tag to all Cards that already have tags
</$button>

<$button>
<$list variable=cur_card filter="[tag[COPY]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[remove[COPY]]"/>
</$list>
Remove COPY tag from all Cards
</$button>

TiddlyWiki\Backlink to HTML,HTM

Title = ext TW Return

```
\define TW_Return(ur_url, ur_link_title)
<div style="float:right"><a href="$ur_url$"> ($ur_link_title$)</a></div>
\end
<$list filter="[<tv-config-toolbar-icons>match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="TiddlyWiki view of website" />
</$list>
</$list>
<$list filter="[<tv-config-toolbar-icons>!match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]split[.htm]join[.html]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="Static HTML view of website" />
</$list>
</$list>

TiddlyWiki\Button navigate to Card

```
<$vars new_code="Test1">
<$list variable=new_pk filter="[<new_code>addprefix[$:/state/popup/]]">
<$button>
<$action-sendmessage $message="tm-new-tiddler" title=<<new_pk>> tags="OneTag [[Another Tag]]" text=<<now "Today is DDth, MMM YYYY">>/>
Create Code ''<<new_code>>'' and Edit
</$button><br>

<$button>
<$action-setfield $tiddler=<<new_pk>> text="yes"/>
<$action-navigate $to=<<new_pk>>/>
Create Code ''<<new_code>>'' and Show
</$button><br>

<$link to=<<new_pk>> /><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
Close Code: ''<<new_code>>''
</$button><br>

<$list filter="[<currentTiddler>!prefix[Draft of]]" variable=strCARD_PK>
<$button>
<$list filter="[list[$:/StoryList]] -[<strCARD_PK>]" variable=strCLOSE_PK>
<$action-sendmessage $message="tm-close-tiddler" $param=<<strCLOSE_PK>>/>
</$list>
Close all other open Codes
</$button>
</$list><br>

<$button>
<$action-sendmessage $message="tm-delete-tiddler" $param=<<new_pk>> />
Delete Card: ''<<new_card>>'' with confirmation
</$button><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
<$action-deletetiddler $tiddler=<<new_pk>> />
Delete Card: ''<<new_card>>'' without confirmation
</$button>
</$list><!--new_pk-->
</$vars><!--new_card-->

TiddlyWiki\Button Set Field

```
<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="yes"/>
Set UrCardPK = yes
</$button>

<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="no"/>
Set UrCardPK = no
</$button>

TiddlyWiki\Checkbox edit

```
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler="$:/state/popup/checkUseIt">Use It</$checkbox>

TiddlyWiki\Clipboard Copy

Tags = `$:/tags/Macro`

```
\define cboard_copy(ur_text)
<pre>$ur_text$</pre>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end
\define cboard_pwd(ur_text ur_pk)
<$reveal type="nomatch" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="show">Show</$button>

</$reveal>
<$reveal type="match" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="hide">Hide</$button>
<pre>$ur_text$</pre>
</$reveal>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end

TiddlyWiki\Code View or Copy data

Title = `mcr glbl_code_split`

Tags = `$:/tags/Macro`

```
\define glbl_code_block(ur_card_pk)
[[$ur_card_pk$]]
<$codeblock code={{$ur_card_pk$}} />
\end
\define glbl_code_linenum(ur_card_pk, ur_skip_count, ur_section_size, ur_disp_linenum)
<div style="clear:both">[[$ur_card_pk$]]</div>
<$list filter="[[$ur_skip_count$]!match[]else[0]]" variable=intSKIP_COUNT>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>count[]]" variable=intLINE_COUNT>
<$list filter="[[$ur_section_size$]!match[]!match[0]else<intLINE_COUNT>]" variable=intSECTION_SIZE>
<$list filter="[range<intSECTION_SIZE>]" variable=intCUR_LINE>
<$list filter="[<intCUR_LINE>subtract[1]]" variable=IntREMOVE_LINE>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>butfirst<IntREMOVE_LINE>first[]]" variable=strCUR_LINE>
<$list filter="[[$ur_disp_linenum$]!match[n]!match[0]]"><div style="float:left"><<intCUR_LINE>></div></$list>
<$codeblock code=<<strCUR_LINE>> />
</$list></$list></$list></$list></$list></$list>
\end
\define glbl_code_split_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]splitregexp[\u0009]join[__	__]splitregexp[\u0020]join[__ __]splitregexp[\u0022\u0022\u0022]join[&#x0022;&#x0022;&#x0022;]]"><<currentTiddler>>
</$list></$list>
\end
\define glbl_code_split_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_split_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_split_data()
<$macrocall $name=glbl_code_split_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_split_next_group_disp(ur_rem_counter)
<$list filter="[{$ur_rem_counter$}subtract[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_split_disp(ur_source_card_pk, ur_temp_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to find: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
Source data: [[$ur_source_card_pk$]]<br>
\end
\define glbl_code_split_combine()
$(currentTiddler)$$(str_html_out)$
\end
\define glbl_code_split_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]add[1]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_card_pk>> text="" />
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_split(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_split_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_split_disp ur_source_card_pk=<<source_card_pk>> ur_temp_card_pk=<<temp_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$wikify name=str_html_out text=<<glbl_code_split_data>> >
        <$list filter="[<temp_card_pk>get[text]else[]]"><$vars combine_html_out=<<glbl_code_split_combine>> >
        <$action-setfield $tiddler=<<temp_card_pk>> text=<<combine_html_out>> />
         </$vars></$list>
        <$macrocall $name=glbl_code_split_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> />
        </$wikify>
      
      Find next 100 lines
      </$button><br>

    <$edit-text tiddler=<<temp_card_pk>> autoHeight=no />
    </$vars>
  </$list>
\end
\define glbl_code_disp_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u00A0]join[&nbsp;]splitregexp[\u0009]join[&nbsp;&nbsp;&nbsp;&nbsp;]splitregexp[\u0020]join[&nbsp;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]]"><<currentTiddler>><br></$list></$list>
\end
\define glbl_code_disp_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_disp_data()
<$macrocall $name=glbl_code_disp_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_disp_next_group_disp(ur_rem_counter, ur_oper)
<$list filter="[{$ur_rem_counter$}$ur_oper$[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_disp_disp(ur_source_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to browse: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
\end
\define glbl_code_disp_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_disp(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_disp_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
[[$ur_card_pk$]]<br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_disp_disp ur_source_card_pk=<<source_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="subtract" />
      
      Browse next 100 lines
      </$button><br>
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="add" />
      
      Browse prev 100 lines
      </$button><br>

    <<glbl_code_disp_data>>
    </$vars>
  </$list>
\end

<!--<$macrocall $name=glbl_code_disp ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_disp "WebNotes\Data 1 >>-->

<!--Does not pass through the \u0009 tab or \u00A0 non-breaking space characters. Chrome highlight and copy puts spaces on the clipboard.-->

<!--[[WebNotes\Data]]-->

<!--<$macrocall $name=glbl_code_split ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_block "UrCardPK">>-->

<!--<<glbl_code_linenum "UrCardPK" 0 15 n>>-->

TiddlyWiki\Codeblock Widget

\define sample_data_e1()
```
sample code "here" and "there"
```
\end

\define sample_data_e2()
<$codeblock code="""sample code "here" and "there"
"""/>
\end

\define sample_data_e3() \define sample_data_e3() sample code "here" and "there"

\define sample_data_e4()
\define sample_data_e4()
sample
code """here"""
and "there"
\end <--Last line of macro
\end

\define sample_data_e5()
<$codeblock code={{{ [[UrCardPK]get[text]] }}}/>
\end

<$codeblock code=<<sample_data_e1>>/>

You can use the `<$codeblock>` widget to display text as the three-backticks TiddlyWiki formatting block. Make sure to put an enter at the end of the string if it ends with d-quotes.

<$codeblock code=<<sample_data_e2>>/>

If you need to show text triple d-quotes in a code string, define a macro to return the string literal instead of passing in a code string.

<$codeblock code=<<sample_data_e3>>/>

Make sure to put a leading space or some trailing comment text on any line within the macro that has `\end` by itself. Otherwise the macro definition will end early.

<$codeblock code=<<sample_data_e4>>/>

Another way to display a Card's content is by using the triple-curly-brace inclusion.

<$codeblock code=<<sample_data_e5>>/>

TiddlyWiki\Compare Lines

```
<$diff-text source={{t1}} dest={{mcr glbl_section_disp}}/>
```

Name = mcr glbl_compare_lines

Tag = `$:/tags/Macro`

```
\define glbl_compare_lines_results_table(ur_card_pk, ur_second_pk, ur_row_count)
<table><tr>
<th>''Line''</th>
<th>Show text</th>
<th>First Side<br>Second Side</th>
</tr>
<$list filter="[range<intSECOND_COUNT>subtract[1]]" variable="intCUR_ENTRY">
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]]" variable="strFIRST_LINE">
<$list filter="[{$ur_second_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]!match<strFIRST_LINE>]" variable="strSECOND_LINE">
<tr>
<td rowspan=2>

!!<<intCUR_ENTRY>>
</td>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection1" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine1}!match[]else[0]]" variable=intSTART_LINE><$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_card_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection1"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strFIRST_LINE>> /></td>
</tr>
<tr>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection2" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine2}!match[]else[0]]" variable=intSTART_LINE>
<$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_second_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_second_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection2"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strSECOND_LINE>> /></td>
</tr>
</$list></$list></$list>
</table>
\end
\define glbl_compare_lines(ur_card_pk, ur_second_pk)
<$list filter="[{$ur_card_pk$}splitregexp[\n]count[]]" variable="intFIRST_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]]" variable="intSECOND_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]subtract<intFIRST_COUNT>]" variable="intSECOND_EXTRA">

[[$ur_card_pk$]] line count: <<intFIRST_COUNT>>

[[$ur_second_pk$]] line count: <<intSECOND_COUNT>>

''$ur_second_pk$'' excess line count: ''<<intSECOND_EXTRA>>''

<$macrocall $name=glbl_compare_lines_results_table ur_card_pk="$ur_card_pk$" ur_second_pk="$ur_second_pk$" ur_row_count=<<intSECOND_COUNT>> />
</$list>
</$list>
</$list>
\end

<!--
<$edit-text tiddler="$:/state/popup/CompareText1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>
<$edit-text tiddler="$:/state/popup/CompareText2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>

<<glbl_compare_lines "$:/state/popup/CompareText1" "$:/state/popup/CompareText2">>
-->

TiddlyWiki\Construct a Calendar

```
\define CalendarEntryDay(ur_ymd,ur_d,ur_cur_date)
<$list filter='$ur_ymd$ +[match[$ur_cur_date$]]'>
//''<span style="background-color:yellow">$ur_ymd$</span>''//<br>
</$list>
<$list filter='[prefix[$ur_ymd$]count[]match[0]]'>
<$list filter='$ur_ymd$ +[!match[$ur_cur_date$]]'>
$ur_ymd$<br>
</$list>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]match[1]]">
''d$ur_d$''<br><<currentTiddler>> entry<br>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]!match[0]!match[1]]">
''d$ur_d$''<br><<currentTiddler>> entries<br>
</$list>
\end

\define CalendarEntryMonth(ur_ym,ur_d,ur_cur_date)
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]!match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d0$ur_d$" ur_d="0$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d$ur_d$" ur_d="$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
\end

\define CalendarListDailyThings(day month year)
<$button class='tc-btn-invisible' style='width:100%;height:100%'>
<div style='height:100%;width:100%;position:relative;text-align:left;vertical-align:top;z-index=0'>

<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]!match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_ym="$year$m0$month$" ur_d="$day$"  ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_m="$year$m$month$" ur_d="$day$" ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>


</div>
</$button>
\end
\define date_list_entry(ur_num,ur_cur_date)
<$list filter="[[$ur_num$]match[$ur_cur_date$]]">
//''<span style="background-color:yellow">$ur_cur_date$</span>''//<br>
</$list>
<$list filter="[prefix[$ur_num$]count[]!match[0]]">
<$list filter="[[$ur_num$]!match[$ur_cur_date$]count[]!match[0]]">
$ur_num$<br>
</$list>
</$list>
<<list-links filter:"[prefix[$ur_num$]]" >>
\end
\define date_list_dayunit(ur_num,ur_cur_date)
<$list filter="$ur_num$0 $ur_num$1 $ur_num$2 $ur_num$3 $ur_num$4 $ur_num$5 $ur_num$6 $ur_num$7 $ur_num$8 $ur_num$9">
<$macrocall $name="date_list_entry" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list_daydec(ur_year_month,ur_num,ur_cur_date)
<$list filter="$ur_year_month$d0 $ur_year_month$d1 $ur_year_month$d2 $ur_year_month$d3 $ur_year_month$d4 $ur_year_month$d5 $ur_year_month$d6 $ur_year_month$d7 $ur_year_month$d8 $ur_year_month$d9">
<$macrocall $name="date_list_dayunit" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list(ur_year,ur_month)
<$calendar-month year="$ur_year$" month="$ur_month$" />

<$macrocall $name="date_list_daydec" ur_year_month="$ur_year$m$ur_month$" ur_num=<<currentTiddler>> ur_cur_date=<<now YYYYm0MMd0DD>> />
\end

TiddlyWiki\Core Macro Definition

* Title = `mcr glbl_core_mcr_def`
* Tag = `$:/tags/Macro`

```
\define glbl_core_mcr_def(ur_macro_name)
<$list variable=cur_pk filter="""[[$:/core]get[text]split[define $ur_macro_name$(]butfirst[]split[\n\\end]first[]addprefix[define $ur_macro_name$(]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">
<$codeblock code=<<cur_pk>> />
</$list><!--cur_pk-->
\end
```

* Show all Core macro names and source code

```
<$list variable=show_code_pk filter="[<currentTiddler>split[Draft of]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-checkShowCode]]">
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>

<$list variable=cur_def_text filter="[[$:/core]get[text]split[define ]!prefix[{]!prefix[the]sort[]]">
<$list variable=cur_macro_name filter="[<cur_def_text>split[(]first[]]">
<$list variable=cur_end_text filter="""[<cur_def_text>split[\n\\end]first[]addprefix[define ]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">

!! <<cur_macro_name>>
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]match[yes]]"><$codeblock code=<<cur_end_text>> />
</$list><!--cur_showcode_text-->

</$list><!--cur_end_text-->
</$list><!--cur_macro_name-->
</$list><!--cur_def_text-->
</$list><!--show_code_pk-->
```

TiddlyWiki\CSS Classes

!! New Card page
* Card name = css alternating-rows
* Tag = $:/tags/Stylesheet

```
.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}
```

Note: The @''''@ directive must include the leading period (.) to select a CSS class

```
@@.alternating-rows
<table>
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

TiddlyWiki\CSS without classes

!! Apply stylesheet to all cards

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
.tc-tiddler-body {
  word-break: normal; 
  word-wrap: break-word;
  white-space: pre-wrap;
} 
```

* Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

!! Apply stylesheet to cards with specific tag `linewrap`

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

* Note: Only cards with the `linewrap` tag will use this stylesheet change

!! Apply Styles to In-line Text

* Start a text block with @,,,,@ and the CSS styles with no spaces

Sample Code:

```
@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line
```

<<<
Result:

```
These are
separate lines
here

This is one big line
```
<<<

* or start in the middle of a text block

Sample Code:

```
This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.
```

<<<
Result:

```
This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.
```
<<<

TiddlyWiki\Data Tiddler

Type = `application/x-tiddler-dictionary`

```
3:a
2:b
3:c
```

See list of unique indexes:

```
<$list variable=cur_key filter="[[UrPK]indexes[]]"><<cur_key>>: 
<$list variable=cur_val filter="[[UrPK]getindex<cur_key>]"><<cur_val>><br>
</$list><!--cur_val-->
</$list><!--cur_key-->
```

Use one value (last one if an index is duplicated):

```
-{{UrPK##3}}-


```

[[VBNetCode\Text file to JSON Lines]]

TiddlyWiki\Date Part

Tag = `$:/tags/Macro`

```
\define glbl_dt_ddd()
<div style="clear:right;float:right;background-color:aquamarine;"><<now "YYYYm0MMd0DD DDD pm0hh12\m0mm">></div>
<$list filter="[<currentTiddler>split[Draft of ']join[]split[ ]first[]split[m]join[]split[d]join[]]">
<$view field="title" format="date" template="[UTC]DDD" />
</$list>
\end
```

|!Token |!Substituted Value |
|`DDD` |Day of week in full (eg, "Monday") |
|`ddd` |Short day of week (eg, "Mon") |
|`DD` |Day of month |
|`0DD` |Adds a leading zero |
|`DDth` |Adds a suffix |
|`WW` |ISO-8601 week number of year |
|`0WW` |Adds a leading zero |
|`MMM` |Month in full (eg, "July") |
|`mmm` |Short month (eg, "Jul") |
|`MM` |Month number |
|`0MM` |Adds leading zero |
|`YYYY` |Full year |
|`YY` |Two digit year |
|`wYYYY` |Full year with respect to week number |
|`wYY` |Two digit year with respect to week number |
|`hh` |Hours |
|`0hh` |Adds a leading zero |
|`hh12` |Hours in 12 hour clock |
|`0hh12` |Hours in 12 hour clock with leading zero |
|`mm` |Minutes |
|`0mm` |Minutes with leading zero |
|`ss` |Seconds |
|`0ss` |Seconds with leading zero |
|`XXX` |Milliseconds |
|`0XXX` |Milliseconds with leading zero |
|`am` or `pm` |Lower case AM/PM indicator |
|`AM` or `PM` |Upper case AM/PM indicator |
|`TZD` |Timezone offset |
|`\x` |Used to escape a character that would otherwise have special meaning |
|`[UTC]`|Time-shift the represented date to UTC. Must be at very start of format string|

TiddlyWiki\Decimal To Hex

"""
Name = mcr glbl_dec_to_hex5
Tag = `$:/tags/Macro`
"""

```
\define glbl_dec_to_hex5(ur_code)
<$list filter="[[$ur_code$]divide[16]divide[16]divide[16]divide[16]floor[]]" variable=lvl_x4>
<$list filter="[<lvl_x4>multiply[16]multiply[16]multiply[16]multiply[16]]" variable=lvl_d4>
<$list filter="[[$ur_code$]subtract<lvl_d4>divide[16]divide[16]divide[16]floor[]]" variable=lvl_x3>
<$list filter="[<lvl_x3>multiply[16]multiply[16]multiply[16]]" variable=lvl_d3>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>divide[16]divide[16]floor[]]" variable=lvl_x2>
<$list filter="[<lvl_x2>multiply[16]multiply[16]]" variable=lvl_d2>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>divide[16]floor[]]" variable=lvl_x1>
<$list filter="[<lvl_x1>multiply[16]]" variable=lvl_d1>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>subtract<lvl_d1>]" variable=lvl_xrem>
<$list filter="[range[15]butfirst[9]match<lvl_x4>add[55]] [range[10]subtract[1]match<lvl_x4>add[48]]" variable=lvl_h4>
<$list filter="[range[15]butfirst[9]match<lvl_x3>add[55]] [range[10]subtract[1]match<lvl_x3>add[48]]" variable=lvl_h3>
<$list filter="[range[15]butfirst[9]match<lvl_x2>add[55]] [range[10]subtract[1]match<lvl_x2>add[48]]" variable=lvl_h2>
<$list filter="[range[15]butfirst[9]match<lvl_x1>add[55]] [range[10]subtract[1]match<lvl_x1>add[48]]" variable=lvl_h1>
<$list filter="[range[15]butfirst[9]match<lvl_xrem>add[55]] [range[10]subtract[1]match<lvl_xrem>add[48]]" variable=lvl_hrem>
<$wikify name=str_hex_out text="0x&#<<lvl_h4>>;-&#<<lvl_h3>>;&#<<lvl_h2>>;&#<<lvl_h1>>;&#<<lvl_hrem>>;" >
<<str_hex_out>>
</$wikify>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
\end

TiddlyWiki\Delete All Cards with Tag

```
<$button>
<$list filter="[tag[ARTICLE]]"><$action-sendmessage $message=tm-delete-tiddler $param=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards with Confirmation
</$button>

<$button>
<$list filter="[tag[ARTICLE]]"><$action-deletetiddler $tiddler=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards without Confirmation
</$button>

<$button>
<$list filter="[tag[DOC]]" variable=doc_pk><$list filter="[<doc_pk>fields[]prefix[e]]" variable=field_pk2><$action-deletefield $tiddler=<<doc_pk>> $field=<<field_pk2>> /></$list></$list>
Del fields starting with `E` in DOC tagged Cards
</$button>

TiddlyWiki\DivPop btn

[[DivPop.svg]]

Tag = `$:/tags/ViewToolbar`

```
\define divpop_current(ur_ref)
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text="$ur_ref$"/>
<$action-sendmessage $message="tm-close-tiddler" $param="pop_right"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{DivPop.svg}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text="Popup over Sidebar"/></span>
</$list>
</$button>
\end

<$list filter="[all[current]]">
<$macrocall $name=divpop_current ur_ref=<<currentTiddler>> /> 
</$list>

TiddlyWiki\DivPop glbl

Tag = `$:/tags/BelowStory`

```
<$list filter="[{$:/state/popup/DivPopTitle}is[tiddler]]">
<div style="
position: fixed;
top: 0px;
right: 0px;
width: 350px;
border: 3px solid;
background: white;
bottom: 0%;
">
<div style="overflow-y: scroll; height: 100%;">
<$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
close
</$button>
<$tiddler tiddler=<<currentTiddler>> >
<$transclude mode="block" />
</$tiddler>
</div>
</div>
</$list>

TiddlyWiki\Embed Font

"""
[https://tiddlywiki.narkive.com/bS0CgWKQ/tw-tw5-how-to-embed-a-font-using-font-face-and-data-url]
- Visit: http://www.fontsquirrel.com/tools/webfont-generator
- Upload your font file (".ttf", ".eot", ".woff", etc)
- Select option "Expert"
- Check the option case at CSS >> Base64 Encode
- Generate your webkit -> Downloads file

[stylesheet.zip file]
- Unpack ZIP file -> Downloads file

[stylesheet.css]
- Note: The file's content in Base64 encoded

[Wiki file]
- Drag-drop file to import -> Creates Card
- [styleshee.css Card]
- Make sure the field font-family is what you want
- Tag = $:/tags/Stylesheet
- Tiddler type = Plain text (text/plain)
- Create a new Card and use the font

TiddlyWiki\Encrypt file

"""
[Wiki file]
- [Sidebar, Tools tab]
- Click button Set Password -> Opens dialog
- Password = UrPasswordText
- Repeat password = UrPasswordText
- Click button Set Password -> Closes dialog

[keyboard action SaveAllChanges]
- [<$action-sendmessage $message="tm-download-file"]
- Comment out this tag to keep the HTML Wiki version from being exported
- Save the Wiki file

- Note: The password will be required to start the Wiki application when you open the Wiki file

TiddlyWiki\External Link organization

* Create one Card for each external link in this format
** Title always starts with `ext` and a space, then the external link description
** Tagged as EXT
** Contains one line in this format:

```
[ext[ur_url]]
```

* Reference the Card with the `ext` macro, but don't include the `ext` prefix or the leading space
* The link is shown, and there will be `->` on the right side of the Card window
* This flags links that will open in a new tab, and allows you to easily open the `ext` Card and change the saved link

```
<<ext "UrExternalLinkDiscption">>
```

* Global macro
** Title = mcr glbl_ext
** Tag = $:/tags/Macro
** Main Body text =

```
\define ext(ur_extcard_pk)
{{ext $ur_extcard_pk$}}<div style="float:right">[[_|ext $ur_extcard_pk$]]</div>
\end

TiddlyWiki\Filter Operators

!!Math

"""
abs - calculate the absolute value of a list of numbers
add - treating each input title as a number, add to each the numeric value of the operand
ceil - rounds a list of numbers up to the next largest integer
divide - treating each input title as a number, divide them by the numeric value of the operand
exponential - convert each number to exponential notation with N digits
fixed - convert each number to fixed point notation with N digits after the decimal point
floor - rounds a list of numbers to the largest integer less than or equal to each number
max - treating each input title as a number, take the maximum of its value and the numeric value of the operand
maxall - find the largest of a list of numbers
min - treating each input title as a number, take the minimum of its value and the numeric value of the operand
minall - find the smallest of a list of numbers
multiply - treating each input title as a number, multiply it by the numeric value of the operand
negate - calculate the negation of a list of numbers
precision - convert each number to a string with N significant digits
product - produce the product of the input numbers
remainder - treating each input title as a number, return the remainder when divided by the numeric value of the operand
round - rounds a list of numbers to the nearest integer
sign - return -1, 0 or 1 for a list of numbers according to whether each number is negative, zero, or positive
subtract - treating each input title as a number, subtract from each the numeric value of the operand
sum - produce the sum of the input numbers
trunc - truncates a list of numbers to their integer part, removing any fractional part
untrunc - rounds a list of numbers to the next integer with largest absolute value, that is, away from zero

TiddlyWiki\Fonts via URL

```
<link href='https://fonts.googleapis.com/css?family=Playfair Display' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Sofia' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Alex Brush' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Akronim' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Annie Use Your Telescope' rel='stylesheet'>

@@font-family: 'Playfair Display';
!'Playfair Display'  1234567890 ABC abc
@@

@@font-family: 'Sofia';
!'Sofia'  1234567890 ABC abc
@@

@@font-family: 'Alex Brush';
!'Alex Brush'  1234567890 ABC abc
@@

@@font-family: 'Akronim';
!'Akronim'  1234567890 ABC abc
@@

@@font-family: 'Annie Use Your Telescope';
!'Annie Use Your Telescope'  1234567890 ABC abc
@@

TiddlyWiki\Global Card Footer

Every Card shows the Wikified content of the Card content, followed by the Wikified content of every Card with the tag `$:/tags/ViewTemplate`.

!Example Footer Text

Create a new Card

<<<
template Global Footer
<<<

```
Any Text Here
```

Add the tag:

* $:/tags/ViewTemplate

And then every Card will show the words "Any Text Here" at the bottom of the Card.

!Example Footer Home Button

Create a new Card

<<<
template Home Button
<<<

```
<div style="float:right">{{$:/core/ui/Buttons/home}}</div>
```

Add the tag:

* $:/tags/ViewTemplate

And then every Card will show the "Home" icon at the bottom-right of the Card.



TiddlyWiki\Global Macro

Tag = `$:/tags/Macro`

TiddlyWiki\Group Totals

```
unique_groups()
- find list of titles with UrAttribute
    - [has[UrAttribute]]
- split by the prefix before the first hyphen
    - [<currentTiddler>split[-]nth[1]]
- return each title's prefix followed by a space
    - ><<currentTiddler>> <

unique_counts()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces
    - [<ugrp>split[ ]
- ignore white-space only entries, and sort the rest alphabetically
    - !match[]sort[]
- use "each:value" to get the unique title prefixes in the list
    - each:value[]]
- for each unique title prefix, get a count of titles with UrAttribute
    - [has[UrAttribute]prefixcount[]]

count_size()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces, ignore white-space, sort, use "each:value", store as ur_entry
    - [<ugrp>split[ ]!match[]sort[]each:value[]]
    - ur_entry=<<currentTiddler>>
- for each unique title prefix, only continue where the count of titles with UrAttribute matches the parent unique count
    - [has[UrAttribute]prefix<ur_entry>count[]match[$(currentTiddler)$]]
- find all the titles with the unique title prefix, and return a "1" for each entry
    - [has[UrAttribute]prefix]">1 <

main()
- create a new variable ucnt with the list of title prefixes from unique_counts()
    - <$wikify name=ucnt text=<<unique_counts>>
- split the new variable by spaces, ignore white-space, sort, use "each:value"
    - [split[ ]trim[]!match[]sort[]each:value[]]
- For each unique count,
    - list the entry
    - sum the number of entries returned from count_size() divided by the unique count
```

```
\define unique_groups()
<$list filter="[has[eng-vocab]]"><$list filter="[<currentTiddler>split[-]nth[1]]"><<currentTiddler>> </$list></$list>
\end
\define unique_counts()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]">
<$list filter="[has[eng-vocab]prefix<currentTiddler>count[]]"><<currentTiddler>> </$list>
</$list>
</$wikify>
\end
\define count_size()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]"><$vars ur_entry=<<currentTiddler>> >
<$list filter="[has[eng-vocab]prefix<ur_entry>count[]match[$(currentTiddler)$]]">
<$list filter="[has[eng-vocab]prefix<ur_entry>]">1 </$list>
</$list>
</$vars></$list>
</$wikify>
\end
<$wikify name=ucnt text=<<unique_counts>> >
<$list filter="[<ucnt>split[ ]trim[]!match[]sort[]each:value[]]">
ASLSJ Prefix Groups with <<currentTiddler>> words -
<$wikify name=usize text=<<count_size>> >
<$list filter="[<usize>split[ ]trim[]!match[]sum[]divide<currentTiddler>]"><<currentTiddler>><br>
</$list>
</$wikify>
</$list>
</$wikify>
```

TiddlyWiki\Hard Line Breaks

HTML normally ignores line breaks. TiddlyWiki uses HTML, and includes a way to stop ignoring line breaks.

[TiddlyWiki editor]
- Type three double-quotes (`"""`) and press enter to ignore line breaks below this point
- The (`"""`) does not show up in the output

Three double-quotes will start a hard line breaks section

```
"""
```

```
line one blends into line two continues

"""
line three stops
line four starts
"""
```

line one blends into
line two continues

"""
line three stops
line four starts
"""

!!HTML Preformatted text with Sans-Serif font

`<pre style="font-family: sans-serif;">line three stops
line four starts</pre>`

<pre style="font-family: sans-serif;">line three stops
line four starts</pre>

TiddlyWiki\Hidden on Static File

!! Hide section when exported to static HTML file

```
<$list filter="[<tv-config-toolbar-icons>match[no]]">
```

TiddlyWiki\iFrame

Use an iFrame to run JavaScript in a TiddlyWiki

```
>iframe src="javascript:newWindow='';var ...
```

- just `javascript:newWindow=var ...` did not compile. An empty string is a work-around.

Alternative output: use alert instead of document.write

```
alert(strTEXT);"/>
```

How to reference an external HTML file in a tiddler

```
>iframe src=...  scrolling=yes style="border-style:none;height:100%;width:100%">
>/iframe>
```

- A self-closing tag does not allow remaining html code to be displayed
- ALWAYS specify a closing >/iframe> tag

TW Macro to show iframe and link

```
>div style='float:right'>[ext[_ |$ur_pk$.txt.html]]
>/div>
>iframe src='$ur_pk$.txt.html'>
>/iframe>
```

- $macrocall $name=iframe_txt ur_pk= currentTiddler

```
<iframe src="javascript:newWindow='';var qs = '&quot;';var qt = '&apos;';

var objFRAME = document.createElement('iframe');
objFRAME.setAttribute('id', 'innerFrame');
objFRAME.setAttribute('src', 'http://www.google.com/');
document.body.appendChild(objFRAME); 
var objTEST = objFRAME;
var strTEXT = '';
if (objTEST===undefined) {
strTEXT = 'undef obj';
} else if (objTEST===null) {
strTEXT = 'null obj';
} else {
var intSEQ = 0;
var strNAME;
for (strNAME in objTEST) {
intSEQ += 1;
strTEXT += ' ; ' + strNAME;
}
strTEXT = 'olen ' + intSEQ + strTEXT;
}
document.write(strTEXT);"></iframe>

alert(strTEXT);"/>

<iframe src='iframe.scrE2.txt' height=100% width=100% scrolling=yes frameborder=no></iframe>


\define iframe_txt(ur_pk)
<div style="float:right">[ext[_ |$ur_pk$.txt.html]]</div>
<iframe src='$ur_pk$.txt.html' scrolling=yes style="border-style:none;height:100%;width:100%"></iframe>
\end

TiddlyWiki\Ignore WikiText formatting

!! Use the TextWidget to ignore WikiText formatting

* widget name = `$text`
* `text` attr = <$text text="`still black colored text`" />

!! Sample code

```
<$text text="`still black colored text`" />
```

<<<
Results:

<$text text="`still black colored text`" />
<<<
!! Use the Rules card pragma to ignore WikiText formatting

* [New card]
* Put `\rules only` at the top of the card text

!! Sample code

```
\rules only
`still black colored text`
```

<<<
Results:

<$text text="`still black colored text`" />
<<<

!! Use the Card Datatype to ignore WikiText formatting

* [New card]
* `type` field = `text/plain`

!! Sample code

```
`still black colored text`
```

<<<
Results:

```
`still black colored text`
```
<<<

TiddlyWiki\Image

"""
Link an image in a Tiddler with 500px width
- Have image tiddler
- Have text tiddler
- Apply image to text tiddler at 500px width

[New tiddler]
- title = mcr img_link
- tag = $:/tags/Macro
- text field code
"""

```
\define img_link(ur_pk)
@@max-width:500px;
[img [$ur_pk$]]
@@
\end
```

"""
[Text tiddler]
- $macrocall $name=img_link ur_pk= currentTiddler
"""

TiddlyWiki\Image link opens Card

Tag = `$:/tags/Macro`

```
\define glbl_image_high(ur_image_pk, ur_size:200)
<$link to="$ur_image_pk$">[img height=$ur_size$px [$ur_image_pk$]]</$link>
\end
\define glbl_image_wide(ur_image_pk, ur_size:500)
<$link to="$ur_image_pk$">[img width=$ur_size$px [$ur_image_pk$]]</$link>
\end

TiddlyWiki\Import Macros

```
\import [[mcr date_list]]

TiddlyWiki\Javascript Calculation in Bookmarklet

* Click the button to copy the text to a javascript bookmarklet
* Open a new tab
* Type the letter "j" in the address bar, paste in the clipboard text, and press enter
* The Javascript alert box shows the message

```
\define glbl_copyto_js_bookmarklet(ur_js_code)
<pre>$ur_js_code$</pre>
<$macrocall $name="copy-to-clipboard" src="""avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){const el = newWindow.document.createElement('textarea');const ur_str='$ur_js_code$';try {el.value =eval(ur_str)}catch(err) {el.value = err.message;}; newWindow.document.body.appendChild(el); el.select();void(newWindow.focus());}""" />
\end

<!--|v
<<glbl_copyto_js_bookmarklet """parseInt("FF",16).toString(10);""">>
^|-->

TiddlyWiki\Keep words together on one line

!! Use CSS white-space tag

* The CSS `white-space:nowrap;` disables normal text wrapping
* This is useful when you have several smaller phrases that should not be separated visually onto different lines
* Note: This can make the line extend past the edge of the browser window, requiring scrolling to see the rest

!!Sample Code that can split phrases

```
A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)
```

<<<
Results:

A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)
<<<

!!Sample Code that can keeps short phrases together

```
@@white-space:nowrap;A code line (1)@@ @@white-space:nowrap;A code line (2)@@ @@white-space:nowrap;A code line (3)@@ @@white-space:nowrap;A code line (4)@@ @@white-space:nowrap;A code line (5)@@ @@white-space:nowrap;A code line (6)@@ @@white-space:nowrap;A code line (7)@@ @@white-space:nowrap;A code line (8)@@ @@white-space:nowrap;A code line (9)@@ @@white-space:nowrap;A code line (10)@@ @@white-space:nowrap;A code line (11)@@ @@white-space:nowrap;A code line (12)@@ @@white-space:nowrap;A code line (13)@@ @@white-space:nowrap;A code line (14)@@
```

<<<
Results:

@@white-space:nowrap;A code line (1)@@ @@white-space:nowrap;A code line (2)@@ @@white-space:nowrap;A code line (3)@@ @@white-space:nowrap;A code line (4)@@ @@white-space:nowrap;A code line (5)@@ @@white-space:nowrap;A code line (6)@@ @@white-space:nowrap;A code line (7)@@ @@white-space:nowrap;A code line (8)@@ @@white-space:nowrap;A code line (9)@@ @@white-space:nowrap;A code line (10)@@ @@white-space:nowrap;A code line (11)@@ @@white-space:nowrap;A code line (12)@@ @@white-space:nowrap;A code line (13)@@ @@white-space:nowrap;A code line (14)@@
<<<

TiddlyWiki\Keyboard Shortcut

!!Pre-requisites

* You need a `ur_message_to_send` to replace in the below steps
** `tm-home` is an example message that TiddlyWiki can do
* You need a `ur_card_pk` to replace in the below steps
** It should describe the desired action

!!Setup keyboard shortcut

[New Card]

* Title = $:/config/ShortcutInfo/ur_card_pk
* Main Body text is blank

[New Card]

* Title = $:/config/shortcuts/ur_card_pk
* Main Body Text =

```
alt-H
```

[New Card]

* Title = keyboard action ur_card_pk
* Tag = $:/tags/KeyboardShortcut
* Field-Value: key =

```
((ur_card_pk))
```

* Main Body Text =

```
<$action-sendmessage $message="ur_message_to_send"/>
```

TiddlyWiki\List Links from Numbered Fields

```
<ol>
<$list filter="[<currentTiddler>fields[]prefix[e]sort[]]" variable=lookup_name>
<$list filter="[<currentTiddler>get<lookup_name>]" variable=ref_card_pk>
<$list filter="[<ref_card_pk>get[img]else[]]" variable=ref_img_pk>
<li><$link to=<<ref_card_pk>> />@@float: right;overflow: auto;vertical-align: top;padding-left: 10px;<$image width=200px source=<<ref_img_pk>> />@@<div style="clear:both;"></div></li>
</$list>
</$list>
</$list>
</ol>

TiddlyWiki\List Links of Prefixed Cards

```
<ol>
<$list filter="[<currentTiddler>addsuffix[\]]">
<$list filter="[all[tiddlers]prefix<currentTiddler>sort[]]">
<li><$link to=<<currentTiddler>> /></li>
</$list>
</$list>
</ol>

TiddlyWiki\List Links standard

```
<<list-links filter:"[tag[DOC]field:level[1]sort[title]] [tag[DOC]field:level[]sort[title]]">>

TiddlyWiki\List Widget

! Content and Attributes

The content of the `<$list>` widget is an optional template to use for rendering each tiddler in the list.

The action of the list widget depends on the results of the filter combined with several options for specifying the template:

* If the filter evaluates to an empty list, the text of the ''emptyMessage'' attribute is rendered, and all other templates are ignored
* Otherwise, if the ''template'' attribute is specified then it is taken as the title of a tiddler to use as a template for rendering each item of the list
* Otherwise, if the list widget content is not blank, it is used as a template for rendering each item of the list
* Otherwise, a default template is used consisting of a `<span>` or `<div>` element wrapped around a link to the item

|!Attribute |!Description |
|filter |The [[tiddler filter|Filters]] to display |
|template |The title of a template tiddler for transcluding each tiddler in the list. When no template is specified, the body of the ListWidget serves as the item template. With no body, a simple link to the tiddler is returned. |
|editTemplate |An alternative template to use for [[DraftTiddlers|DraftMechanism]] in edit mode |
|variable |The name for a [[variable|Variables]] in which the title of each listed tiddler is stored. Defaults to ''currentTiddler'' |
|emptyMessage |Message to be displayed when the list is empty |
|storyview |Optional name of module responsible for animating/processing the list |
|history |The title of the tiddler containing the navigation history |

!! Additional Notes and Edge Cases

* If the `filter` attribute is not present then a default of `[!is[system]sort[title]]` is used
* If the list widget is completely empty (ie only whitespace between the opening and closing tags), then it behaves as if the content were a `DIV` or a `SPAN` containing a link to the current tiddler (it’s a `DIV` if the list widget is in block mode, or a SPAN if it is in inline mode)
* If the `template` attribute is not present then the content of the list widget will be used as the template, unless the widget is completely empty in which case a default template is used

TiddlyWiki\Local Video or Audio Files

```
<video width="320" height="180"
poster="video\Frozen Sleep - Cortana Tribute by Malukah.png"
controls preload="none">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.webm" type=
"video/webm">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.ogv" type=
"video/ogg">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.mp4" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
```

```
<audio controls preload="none">
<source src="audio\Frozen-Sleep-Malukah.ogg" type="audio/ogg">
<source src="audio\Frozen-Sleep-Malukah.mp3" type="audio/mp3">
<p>Your browser does not support the HTML 5 audio tag.</p>
</audio>
```

TiddlyWiki\Pagination

```
\define page_next()
<$list variable="filter_prev_page" filter="[<page_pk>get[text]!match[0]!match[]]">
<$button style="margin-left:30px">
<$action-setfield $tiddler=<<page_pk>> text=""/>
First page
</$button>

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>subtract[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/></$list>
Previous page
</$button>
</$list><!--filter_prev_page-->

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>add[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/><$action-navigate $to=<<card_pk>> $scroll="yes"/></$list>
Next page
</$button><br>
<!--***page_next***-->
\end
<$list variable="card_pk" filter="[<currentTiddler>]">
<$list variable="popup_pk" filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]">

<$list variable="page_pk" filter="[<popup_pk>addsuffix[-cur_page]]">
<$list variable="cur_page_skip" filter="[<page_pk>get[text]!match[]else[0]]">
<$list variable="cur_page_num"filter="[<cur_page_skip>add[1]]">
<$list variable="cur_page_through" filter="[<cur_page_num>subtract[1]add[10]]">
<<page_next>>

<$list variable="subdir_count" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]count[]]">

Subdirectories <<cur_page_num>> through <<cur_page_through>>

Number of subdirectories: <<subdir_count>><br>
<$list variable="cur_subdir_path" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]butfirst<cur_page_num>first[10]]">

<$list variable="raw_image_count" filter="[{File List Data}splitregexp[\n]prefix<cur_subdir_path>uppercase[]suffix[.JPG]count[]addprefix[ (]addprefix<cur_subdir_name>addsuffix[ photo]]">
<<raw_image_count>>
</$list><!--raw_image_count-->

</$list><!--cur_subdir_path-->
</$list><!--subdir_count-->
<<page_next>>
</$list><!--cur_page_through-->
</$list><!--cur_page_num-->
</$list><!--page_pk-->
</$list><!--popup_pk-->
</$list><!--card_pk-->

TiddlyWiki\Popup State Clear All

```
<$list filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]" variable="popup_pk">
<$button>
<$list filter="[all[tiddlers]prefix<popup_pk>has[text]]" variable=del_pk><$action-deletefield $tiddler=<<del_pk>> $field="text"/></$list>
Show All
</$button><br>

</$list>

TiddlyWiki\Published Tools

https://dynalist.io/d/zUP-nIWu2FFoXH-oM7L7d9DM#z=zdF80rIaJ79W5P0IGsjYIjkD

"""
[Ace editor](http://innoq.tiddlyspot.com/)
[ActionIncrement widget](https://skeeve.github.io/tw5-plugins/) - The action-increment widget is an action widget that retrieves a value from a text reference. It will then increase the first digit-sequence found in that text and store it.
[Ad-Hoc Macro](https://tobibeer.github.io/tb5/#Ad-Hoc%20Macro) - evaluate any text as an ad-hoc macro even passing variables.
[Amazon Web Services Plugin](https://tiddlywiki.com/#OfficialPlugins) - provides several tools for working with Amazon Web Services **(official TW plugin)**
[Delay Actions](https://groups.google.com/forum/#!topic/tiddlywiki/z7SGLAPODW8), defer the execution of action widgets for a set amount of time
[CouchDB adaptor](https://github.com/wshallum/couchadaptor)
[Count (tobibeer)](http://tobibeer.github.io/tw5-plugins/#count) - A filter to count titles or compare against a specified count
[Demo Code Macro](http://ooktech.com/jed/ExampleWikis/DemoCodeMacro/) - This is an attempt to make a macro that can be used to demonstrate wikitext code fragments in an interactive way.
[dom (tobibeer)](http://tobibeer.github.io/tw5-plugins/#dom) - retrieve text or attributes from dom nodes
[eval (tobibeer)](http://tobibeer.github.io/tw5-plugins/#eval) - Evaluate expressions, compute and compare tiddler properties and data
[Fargo.io integration](http://blog.jeffreykishner.com/2014/01/24/note-taking-bookmarklets-for-fargoio-and-tiddlywiki-.html)
[Global macros, instructions on how to make](http://tw5magick.tiddlyspot.com/)
[Highlight plugin](https://tiddlywiki.com/plugins/tiddlywiki/highlight/#%24%3A%2Fplugins%2Ftiddlywiki%2Fhighlight) **(official TW plugin)** - description: Plugin that activates syntax highlighting of code blocks using v8.8.0 of highlight.js from Ivan Sagalaev. demo [here](https://tiddlywiki.com/plugins/tiddlywiki/highlight/)
[HTAlink](http://welford.github.io/) - Will only work in offline hta editions of this page. Launches external links in your default browser and not IE
[ifAisB](https://tid.li/tw5/hacks.html) - This macro allows to test if a value A – a variable or a transcluded value – matches a value B and to react accordingly. It works almost like an if-then-else statement.
[IfTid Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the existence of a tiddler (or field) and to send different widget messages based upon the existence of this tiddler (or field.) 
[IfTref Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the value of a TextReference and to send different widget messages based upon whether this value matches the value specified by the 'value=' attribute.
[Incremental load command](http://malsandbox.tiddlyspot.com/) - only loads tiddlers that either don't already exist in the tiddlers folder, or have a newer modified date than the existing tiddler.
[Javascript macros in wikitext](http://tw5magick.tiddlyspot.com/)
[JSON editor (btheado)](http://btheado.github.io/jsoneditor.html)
[JSON editor (bjtools)](http://bjtools.tiddlyspot.com/)
[JsonMangler](https://joshuafontany.github.io/TW5-JsonMangler/) - This plugin changes the methods tiddlywiki uses to retrieve and set values in json data tiddlers. It does this in a way that aims for backwards compatibility.

[keyboard-snippets plugin](http://braintest.tiddlyspot.com/#keyboard-snippets)
[LetWidget](http://tiddlystuff.tiddlyspot.com/) - The LetWidget is an enhancement of the SetWidget.
[mforth](https://quaraman.de/tw/mforth.html) - It is a forth like language in a tiddlywiki macro. Forth operates with Reverse Polish Notation (RPN for short).
[Mousetrap](http://welford.github.io/) - simple library for handling keyboard shortcuts in Javascript.
[muut integration](http://ooktech.com/jed/ExampleWikis/TiddlyWiki-muut/)
[Nodewebkitsaver plugin](http://ooktech.com/jed/ExampleWikis/SetFilters/#%24%3A%2Fplugins%2FOokTech%2FSetFilters) - provides a saver module for saving changes when using [TiddlyWiki](http://ooktech.com/jed/ExampleWikis/SetFilters/#TiddlyWiki) directly under NW.js (previously known as node-webkit).
[Pack as plugin](http://braintest.tiddlyspot.com/#Pack%20as%20plugin) - Beta version
[Pan widget](http://muritest.tiddlyspot.com) - This widget is touch sensitive. It is able to trigger actions as the start and end of pans. Multiple differntial pans are possible.
[Persistent-states](https://wikilabs.github.io/#persistent-states) and [Remove-states](https://wikilabs.github.io/#remove-states)
[pick Plugin](https://skeeve.github.io/tw5-plugins/) - The pick plugin is a set of two filters and one widget to help extracting data from your TiddlyWiki file.
[PluginSize](https://tid.li/tw5/plugins.html#%24%3A%2Fplugins%2Ftelmiger%2FPluginSize:%24%3A%2Fplugins%2Ftelmiger%2FPluginSize) - This plugin calculates the size of all installed plugins, including themes and languages.
[PluginDevelopment](https://github.com/inmysocks/PluginDevelopment) -- Scripts to help you create plugins and plugin libraries for node.js
[pv5](http://pv5.tiddlyspot.com/) - testing params and variables
[random (tobibeer)](http://tobibeer.github.io/tw5-plugins/#random) - A filter to return one or more random titles
[ReplacePragma](http://tiddlystuff.tiddlyspot.com/)
[Save trail plugin](https://tiddlywiki.com/#OfficialPlugins) - This plugin causes TiddlyWiki to continuously download (as a JSON file) the contents of any tiddler that is manually changed by any of several means **(official TW plugin)**
[setvars (tobibeer)](http://tobibeer.github.io/tw5-plugins/#setvars) - Set multiple, complex variables based on attributes, filters, or conditionals
[Shuffle filter operator](https://mklauber.github.io/tw5-plugins/#Shuffle%20Operator) - implements a new filter operator called Shuffle. This operator takes the input list and randomizes the order of the list. If no parameter is provided, the list order is random every time.
[SPilot4Tw](https://www.quaraman.de/tw/pilot.html) - A programming language that can be included as Tiddlywiki plugin.
[Startup Actions demo](http://ooktech.com/jed/ExampleWikis/StartupActions/) - A plugin to add startup scripts to TiddlyWiki 
[style (tobibeer)](http://tobibeer.github.io/tw/style/#GettingStarted) - This wiki introduces you to using your desktop browser to inspect the styles applied to elements in TiddlyWiki and permanently change them.
[Three.js](http://rboue.tiddlyspot.com/#Three.js%2Fintroduction) - 3D modeling
[TiddlyWiki5 Coding](http://cjhunt.github.io/) - These pages document aspects TiddlyWiki5 programming, sharing "lessons learned" to help developers to get started with TiddlyWiki5 customization and extension. (FYI - 4 years old)
[Tinka](https://tinkaplugin.github.io/) - Create and modify plugins in the browser. 
[Trace-variable example](http://eucaly-tw5.tiddlyspot.com/#trace-variable%20Example) - no clue what this is.
[Trigger Actions Demo](http://ooktech.com/jed/ExampleWikis/TriggerActions/)
[Tutorial Maker with HopScotchjs](https://cdn.rawgit.com/abesamma/TW5-tutorial-maker-plugin/29c31124/Demo.html) - a plugin that allows TW5 developers to create interactive product tutorials for their tiddlywiki projects, to guide new users.
[TW Components](https://tw-scripts.github.io/TW-Components/) - A component is a group of TW macros and tiddlers create a visual element for complex processes. The ultimate objective of TW components is to create objects which can simply by used by TW programmer to create complex plugins or codes.
[twexe - run exe's from hta files](https://github.com/welford/twexe) - only works in offline hta versions of TW. It lets you register and run exes from tiddlywiki

TiddlyWiki\Recently Changed Cards

```
<<timeline limit:30 format:"YYYY-0MM-0DD">>

TiddlyWiki\Regular Expression

```
<!--|v
Split at Regular Expression skips everything before the first period -> `.12`,  `.1` and `.or.maybe.1`
^|-->

<$vars re="^[^\.]*">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>

<!--|v
Split at Regular Expression skips everything before the last period -> `1`,  `1` and `1`

Each:Value gets the unique list of entries -> `2` and `1`

Sort orders them numberically
^|-->

<$vars re="^.*\.">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>!match[]each:value[]sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>


<!--|v
Split
^|-->

<!--<$vars re="^[^\.]*"> skip up to first period excluded-->
<!--<$vars re="^.*\."> skip up to first period included-->
<$vars card_pk="File List Data" re="^.*\.">
<$list variable="cur_file_ext" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.gif(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.jpeg(?i)]] [<card_pk>get[text]splitregexp[\n]regexp[\.jpg$(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.png(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.tif(?i)]] +[splitregexp<re>!match[]each:value[]sort[]addprefix[.]]">
<$list variable="file_ext_count" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]suffix<cur_file_ext>count[]]">

<<cur_file_ext>>: <<file_ext_count>> files
</$list><!--file_ext_count-->
</$list><!--cur_file_ext-->
</$vars>

TiddlyWiki\Reveal Section and Copy Data

Title = mcr T1Reveal

```
\define t1cb(UrContent)
<$list filter="[[$UrContent$]!match[]]">
$UrContent$
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
\end
\define t1reveal(UrPK UrSeq UrContent)
<$list filter="[[$UrContent$]!match[]]">
<br>
<$reveal type="nomatch" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="show">,,$UrSeq$,,</$button>
</$reveal>
<$reveal type="match" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="hide">^^$UrSeq$^^</$button><br>
"""
$UrContent$
"""
</$reveal>
<$list filter="[[$UrSeq$]match[Pwd]]">
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
</$list>
\end

TiddlyWiki\Save Wiki and Export HTML

```
\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.htm"
/>
<$action-sendmessage $message="tm-download-file"
$param="$:/core/templates/exporters/StaticRiver" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
exportFilter="""[all[tiddlers]tag[INDEX]sort[title]][all[tiddlers]!tag[EXTLINK]!tag[INDEX]!tag[META]!prefix[Draft of]!is[image]!is[tag]!is[system]sort[title]]"""/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.htm]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>

TiddlyWiki\Search all Fields

```
<$vars search_text_pk="$:/state/popup/SearchAllFields">
<$list variable=show_code_pk filter="[<search_text_pk>addsuffix[-checkShowCode]]">
<$list variable=skip_system_pk filter="[<search_text_pk>addsuffix[-checkSkipSystem]]">
<$edit-text tiddler=<<search_text_pk>> field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler=<<skip_system_pk>>> Skip System </$checkbox><br>
<br>

<$list variable=cur_search_text filter="[<search_text_pk>get[text]addsuffix[(?i)]!match[]]">
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]else[no]]">
<$list variable=cur_skipsystem_text filter="[<skip_system_pk>get[text]else[yes]match[yes]count[]]">

<!--Card titles-->
<$list variable=cur_pk filter="[regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_skipsystem_text>] [<cur_pk>!is[system]count[]] +[sum[]match[1]]">

<$link to=<<cur_pk>> />: title
</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

<!--Card fields-->
<$list variable=cur_pk filter="[!regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_pk>is[system]count[]multiply<cur_skipsystem_text>match[0]]">
<$list variable=cur_field filter="[<cur_pk>fields[]]">
<$list variable=found_field filter="[<cur_pk>get<cur_field>regexp<cur_search_text>]">

<$link to=<<cur_pk>> />: <<cur_field>>
<$list variable=disp_code filter="[<cur_showcode_text>match[yes]]">
<$codeblock code=<<found_field>> />
</$list><!--disp_code-->
</$list><!--found_field-->
</$list><!--cur_field-->

</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

</$list><!--cur_skipsystem_text-->
</$list><!--cur_showcode_text-->
</$list><!--cur_search_text-->
</$list><!--skip_system_pk-->
</$list><!--show_code_pk-->
</$vars><!--search_text_pk-->

TiddlyWiki\Section Display

Card name = `mcr glbl_section_disp`

Tag = `$:/tags/Macro`

```
\define glbl_section_disp(ur_title, ur_section_num)
<$reveal type="nomatch" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="show">

!!$ur_title$ - Show
</$button></$reveal>
<$reveal type="match" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">

!!$ur_title$
</$button><br>

<<section$ur_section_num$>>

<$button style="float:right" class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">
---
</$button><br>
</$reveal>
\end
<!--|v
-- Card content call

\define section1()

section content

!!!here

\end
<<glbl_section_disp "Section 1" 1>>
^|-->

TiddlyWiki\Source Code Samples

!!TiddlyWiki Git repository sample code

[Home button]
<<ext "Tiddly Wiki Home Button source code">>

```
{{$:/core/images/home-button}}
```

<<<
{{$:/core/images/home-button}}
<<<


[Save button]
<<ext "TiddlyWiki Save Button source code">>

```
<$action-sendmessage $message="tm-save-wiki" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>
```

* This code says I can specify my own download file name

```
<span class="tc-dirty-indicator">
```

* This code changes the color of elements within the `<span>` to red when the Wiki file has not been saved

[TiddlyWiki TopBar Menu]

<<ext "TiddlyWiki TopBar Menu">>

```
<$button set="$:/state/sidebar" setTo="no"/>
<$button set="$:/state/sidebar" setTo="yes"/>
```

* These lines show that the `$:/state/sidebar` Card is "no" to hide the sidebar, or "yes" show it

TiddlyWiki\Split Lines into Storage

```
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>fields:exclude[created title modified]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<new_line_pk>> $field=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:25px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Temp Table

```
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>indexes[]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<ttbLINE>> $index=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:200px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$link to=<<ttbLINE>> />
<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Text Differences

```
<$diff-text source={{FirstTiddler}} dest={{SecondTiddler}}/>

TiddlyWiki\Textbox field

\define sample_data_e1()
<$edit-text tiddler="$:/state/popup/TestText1" field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
\end

\define sample_data_e2()
<$edit-text tiddler="$:/state/popup/TestText2" field=text default="here" placeholder="[no text yet]" autoHeight=yes tag=textarea/>
\end

You can choose to edit a Card or a Card's field in a single-line or multi-line textbox.

* The `default` parameter is automatically placed in the textbox when the Card does not exist
** Typing in the box will add to the default text
** The Card will be created when the text in the box is changed
** Otherwise the default text will not be saved

* The `placeholder` parameter is shown as greyed-out text when the Card does not exist and there is no default text, or the Card exists and the text field is empty
** Typing in the box will overwrite the placeholder text

Note: Editing a Card PK that starts with `$:/state/popup/` will not be saved and does not affect the Wiki's "dirty" flag

[[$:/state/popup/TestText1]]
<$codeblock code=<<sample_data_e1>> />
<<sample_data_e1>>

---
[[$:/state/popup/TestText2]]
<$codeblock code=<<sample_data_e2>> />
<<sample_data_e2>>

TiddlyWiki\TiddlySaver from Downloads

Make a small form with a timer that moves downloaded TiddlyWiki files back to their original folder

- I have not tried to play around with running TW5 on Node.js. I don't prefer having to use TiddlyDesktop as a separate web browser. Installing a plugin would only save my wiki changes under the downloads directory. I like using a portable web browser on my thumb drive, and I am able to run non-admin programs on my computer. So I made a small program with a timer to move each saved TW file from my Downloads directory back to its original loading location.

- I leave the program running all the time I am logged in. Alt-S saves the data in TiddlyWiki to the Downloads folder. After at most five seconds, the timer moves the file to overwrite the original location. The form flashes on the screen for one second and then hides itself until another move.

1) I created an alt-S shortcut macro to save the current wiki with a specific filename prefix (TWMove_), the entire file path - with substitutions for path-specific characters (: and \), and a time stamp. (Using split/join is accurate enough for me.)

Example: TWMove_C-colon-slash-RootDirOne-slash-SubDirTwo-slash-UrWiki.html

```

\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.html]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>
```

2) I have my web browser save all downloaded files to a specific Downloads folder. (Specifically on Google Chrome, I did install a plugin to automatically hide the dowloaded files bar. It was getting annoying.)

3) I created a small program with a multi-line textbox, and a timer to poll the Downloads folder every five seconds. It moves all the TWMove files in alphabetical order, so the latest timestamped file will be processed last. It finds the destination path as part of the filename. (Moving assumes the original TW.html file is not locked by the browser. This happened to me once, but I just had to restart the browser to release the file lock.)

The program's text box shows the folder I'm polling. When it picks up a file, the original path is pre-pended to the textbox's list of processed files and the form flashes in the foreground for a second. (I could have made a system tray pop-up notification instead.)

It's not perfect, but definitely doable for most amateur programmers.

TiddlyWiki\Transclude Card Field

```
<$transclude mode="block" tiddler=<<currentTiddler>> />

<$transclude mode="inline" tiddler=<<currentTiddler>> field="ref_data" />

TiddlyWiki\Unicode Character List

```
\define CharRef(ur_code, ur_line_grouping)
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]floor[]] " variable=div_val>
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]match<div_val>] "><br><sub>$ur_code$
<<glbl_dec_to_hex5 "$ur_code$">>
</sub><br>
</$list>
</$list>
[&#$ur_code$;]
\end

https://en.wikipedia.org/wiki/Unicode_block

https://en.wikipedia.org/wiki/Plane_(Unicode)


<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text=""/>
Line Grouping = 10
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text="16"/>
Line Grouping = 16
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text=""/>
Clear selection
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="0"/>
Show Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="65536"/>
Show Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="131072"/>
Show Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="196608"/>
Show Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)
</$button>

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

@@font-family: "Lucida Console", Courier, monospace;
<$list filter="[{$:/state/mcr CharRef LineGrouping}!match[]else[10]] " variable=line_grouping>
<$list filter="[[$:/state/mcr CharRef CharacterListBase]get[text]!match[]]">
<$list filter="[range[512]subtract[1]multiply[128]add{$:/state/mcr CharRef CharacterListBase}]" variable=cur_block>
<h2><<cur_block>></h2>
<$list filter="[range[128]subtract[1]] +[add<cur_block>] " variable=cur_code>
<$macrocall $name=CharRef ur_code=<<cur_code>> ur_line_grouping=<<line_grouping>> />
</$list>
</$list>
</$list>
</$list>


TiddlyWiki\Unicode Codepoints Used

```
\define dec_to_u_hex4()
<$list variable=cur_d4 filter="[[$(dec_num)$]divide[16]floor[]divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d4 filter="[[0]subtract<cur_d4>multiply[16]multiply[16]multiply[16]add[$(dec_num)$]]"
><$list variable=cur_d3 filter="[<rem_d4>divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d3 filter="[[0]subtract<cur_d3>multiply[16]multiply[16]add<rem_d4>]"
><$list variable=cur_d2 filter="[<rem_d3>divide[16]floor[]]"
><$list variable=rem_d2 filter="[[0]subtract<cur_d2>multiply[16]add<rem_d3>]"
><$list variable=hex filter="[[;]addsuffix<cur_d4>addsuffix[;]addsuffix<cur_d3>addsuffix[;]addsuffix<cur_d2>addsuffix[;]addsuffix<rem_d2>split[;10]join[A]split[;11]join[B]split[;12]join[C]split[;13]join[D]split[;14]join[E]split[;15]join[F]split[;]join[]]"
>\u<<hex>></$list><!--hex
--></$list><!--rem_d2
--></$list><!--cur_d2
--></$list><!--rem_d3
--></$list><!--cur_d3
--></$list><!--rem_d3
--></$list><!--cur_d4
-->
\end
\define entry_hexcode(ur_char, ur_code_page)
<$list variable=cur_codepage filter="""[[$ur_code_page$]!match[]else[0]multiply[256]]""">
<$list variable=dec_num filter="""[range[256]add<cur_codepage>]""">
<$wikify name=hex_unicode text=<<dec_to_u_hex4>> >
<$list filter="""[[$ur_char$]regexp<hex_unicode>]""" variable=match_text>
-$ur_char$-<<hex_unicode>>-&amp;#<<dec_num>>;
</$list><!--match_text-->
</$wikify><!--hex_unicode-->
</$list><!--cur_unicode-->
</$list><!--cur_unicode-->
\end
\define unicode_points(ur_pk)
<$list variable=code_page filter="[[$:/state/unicode_points_codepage]get[text]else[0]]">

Code page = <<code_page>> <$button

style="margin-left:30px">
<$list variable="next_page" filter="[<code_page>add[1]]"><$action-setfield $tiddler="$:/state/unicode_points_codepage" text=<<next_page>>/></$list>
Next page
</$button><$button

style="margin-left:30px">
<$action-setfield $tiddler="$:/state/unicode_points_codepage" text="0"/>
Reset
</$button><br>


<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]count[]!match[1]!match[0]]">-&#x005D;-\u005D-&amp;#93;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u0060]count[]!match[1]!match[0]]">-&#x0060;-\u0060-&amp;#96;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]join[]splitregexp[\u0060]join[]split[]each:value[]sort[]]">-<<cur_char>>-
<$macrocall $name=entry_hexcode ur_code_page=<<code_page>> ur_char=<<cur_char>> />
<br>
<br>
</$list><!--cur_char-->
</$list><!--code_page-->
\end

<<unicode_points "UrPK">>

TiddlyWiki\Upload File

!! Drag and drop
* Drag a file icon from the Windows Desktop or Windows Explorer over the Wiki until you see a top-margin green bar show
* Release the mouse to drop the file -> Opens card

!! Import Card
* Review the file list and uncheck and undesired import objects
* Click button Import -> Creates Cards

!! BrowseWidget

* Create a $browse tag -> Makes button
* Click button Choose File -> Opens dialog
* Choose a file -> Closes dialog, opens Card

!! Import Card
* Review the file list and uncheck and undesired import objects
* Click button Import -> Creates Cards

```
<$browse />
```

TiddlyWiki\Video and Audio

* Title = mcr glbl_ext_av
* Tag = `$:/tags/Macro`
* Note: The paths are relative to the current website. You cannot load Video or Audio content from other websites due to browser restrictions.

* Note: You can add attribute `poster="placeholder.png" ` to the Video tag if you have a specific image you want instead of the video's first frame

```
\define glbl_ext_video(UrFolder,UrVideo,UrTime)
<video width="320" height="180"
controls preload="metadata">
<source src="$UrFolder$/$UrVideo$.mp4#t=$UrTime$" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
\end
\define glbl_ext_audio(UrFolder,UrAudio,UrTime)
<audio controls preload="none">
<source src="$UrFolder$/$UrAudio$.mp3#t=$UrTime$" type=
"audio/mp3">
Your browser does not support the HTML 5 audio tag.
</audio>
\end

<!--|v
* Hard-coded to only use MP4 files

<<glbl_ext_video "MyVideosSubFolder" "MyVideoFile" "00:01:00">>

<<glbl_ext_video "file:///C:/UrFolder/UrSubFolder" "UrFilenameNoExtension" "00:01:00">>
^|-->
<!--|v
<<glbl_ext_audio "MyAudioSubFolder" "MyAudioFile" "00:01:00">>
^|-->

TiddlyWiki\View All Cards

```
<$list filter="[all[tiddlers]!tag[EXTLINK]!tag[IMG]!tag[INDEX]!tag[MCR]!tag[META]!has[draft.of]!is[image]!is[tag]!is[system]has[tags]!prefix[undefined]sort[title]]">
<hr>
<h2><$link to=<<currentTiddler>> /></h2>
{{||$:/core/ui/ViewTemplate/tags}}
<$transclude mode="block"/>
</$list>

TiddlyWiki\Wikify Text

```
<$wikify name=str_text_out text="&#65;">
A = <<str_text_out>>
</$wikify>

<$wikify name=str_text_out text="''bold font''" output=html>
B = <<str_text_out>>
</$wikify>

TiddlyWiki\WikiText Formatting

You can type most standard text without problems. Leading, repeated, or paired special characters may need escaped.

!Vertical Spacing

```
Pressing enter at the end of a line does not start a new paragraph.
Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph.
Press enter twice.
```

For example, see how the above two paragraphs are shown below:

Pressing enter at the end of a line does not start a new paragraph.
Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph.
Press enter twice.


!Leading Special Characters

!!Bulleted List Entry

```
*Bulleted List Entry
```

*Bulleted List Entry

Leading with an asterisk creates a bulleted list entry. To escape, prefix with four single-quotes.

If you want a single blank line between two bullet points, use a !''''! Heading Line without any title text.

```
''''*Bulleted List Entry
```

''''*Bulleted List Entry

!!Heading Line

```
!Heading Line
```

Starting a new paragraph line with an exclamation mark (!) results in a heading line.

```
!Heading Line
```

The above heading markup starts with an exclamation mark. To escape, prefix with four single-quotes.

```
''''!Heading Line
```

''''!Heading Line

!!Mono-spaced Text Block

```
 ```
 Mono-spaced Text Block
 ```
```

```
Mono-spaced Text Block
```

Leading with a triple back-tick creates a mono-space text block. To escape, surround the triple back-tick with doubled square-brackets.

```
[[''']] Regular typeface
```

[[```]] Regular typeface

!!Numbered List Entry

```
#Numbered List Entry
```

#Numbered List Entry

Leading with a pound-sign creates a numbered list entry. To escape, prefix with four single-quotes.

```
''''#Numbered List Entry
```

''''#Numbered List Entry

!!Quoted text block
```
<<<
Quoted text block
<<<
```

<<<
Quoted text block
<<<

Leading with a triple less-than creates a quoted text block. To escape, surround the 

```
''''<<< Unquoted text
```

''''<<< Unquoted text

!!URL Links

```
https://tiddlywiki.com/
```

https://tiddlywiki.com/

Start text with an "http'''':/''''/" "http'''':/''''/" will create a URL link. To escape, place four single-quotes before the colon and between the double forward-slashes.

```
https'''':/''''/tiddlywiki.com/
```

https'''':/''''/tiddlywiki.com/


!Repeated Special Characters

```
''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`
```

''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`

A number of repeated special characters are used as Wiki Markup to format text. To escape, place four single-quotes between the doubled characters or surround the doubled characters with doubled square-braces.

```
[['']]Bold Text[['']] /''''/Italic Text/''''/ ~''''~Strike-through Text~''''~ _''''_Underlined Text_''''_ ^''''^Raised-Small Text^''''^ ,'''',Lowered-Small Text,'''', [[`]]Mono-spaced Text[[`]]
```

[['']]Bold Text[['']] /''''/Italic Text/''''/ ~''''~Strike-through Text~''''~ _''''_Underlined Text_''''_ ^''''^Raised-Small Text^''''^ ,'''',Lowered-Small Text,'''', [[`]]Mono-spaced Text[[`]]

!Paired Special Characters

!!Literal Text

```
[[Literal Text]]
```

[[Literal Text]]

Surrounding text with doubled square-brackets shows the literal surrounded text without applying formatting. To escape, place four single-quotes between the first doubled square-brackets.

```
[''''[Literal Text]]
```

[''''[Literal Text]]

!!Transcluded Text

```
{{Other Tiddler Title}}

Note: The other tidder's content is "Other Tiddler Transcluded Text".
```

{{Other Tiddler Title}}

Surrounding text with doubled curly-braces shows the full content of another tiddler. To escape, place four single-quotes between the first doubled curly-braces.

```
{''''{Other Tiddler Title}}
```

{''''{Other Tiddler Title}}

!!HTML Markup

```
<b>HTML Markup</b>
```

<b>HTML Markup</b>

Surrounding text with angled-brackets uses HTML formatting. To escape, rename the first angle-bracket to &lt'''';

```
&lt;b>HTML Markup</b>
```

&lt;b>HTML Markup</b>

!!HTML Literals

```
&lt;

Note: &lt; represents a left angle-bracket, or the less-than symbol (<).
```

&lt;

Surrounding text with an ampersand (&) and a semi-colon translate to an HTML literal. To escape, place four single-quotes after the ampersand.

```
&lt;
```

&''''lt;


!!CSS Styles

You can apply CSS styles in-line with the text. Make sure you put the semi-colon at the end of the style list.

```
You can apply @@background-color:yellow; CSS styles @@ in-line with the text.
```

You can apply @@background-color:yellow; CSS styles @@ in-line with the text.


!!Tables

```
|!Cell1 |!Cell2 |
|Cell3 |Cell3 |

|^top left |^ top center |^ top right|
|middle left | middle center | middle right|
|,bottom left |, bottom center |, bottom right|


To merge a table cell with the one above, use the special cell text ~. To merge a cell with the one to its left use the text <. To merge one to its right use >. For example:

|Cell1 |Cell2 |Cell3 |Cell4 |
|Cell5 |Cell6 |Cell7 |<|
|Cell5 |~|Cell7 |Cell8 |
|>|Cell9 |Cell10 |Cell11 |

assigns the CSS classes "myclass" and "anotherClass" to the table
gives the table the caption "This is a caption"
adds a header row of cells with the text "Header"
adds a footer row of cells with the text "Footer"
|myclass anotherClass|k
|This is a caption |c
|Cell1 |Cell2 |
|Cell3 |Cell3 |
|Header|Header|h
|Footer|Footer|f
```

TiddlyWiki\Word Wrap

!! Hard-line breaks using CSS styles

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
.tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

* Note: When using this alternate CSS, wiki text markup will be ignored unless preceded by a double-spaced line
* Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

Sample Code:

```
*bullet 1
*bullet 2
*bullet 3
Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a ",,,,",,,," wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

*bullet 4 requires a preceding double-spaced line to be interpreted as wikitext
```

<<<
Results:

```
* bullet 1
* bullet 2
* bullet 3

Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a """ wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

* bullet 4 requires a preceding double-spaced line to be interpreted as wikitext
```
<<<

!! Apply stylesheet to cards with specific tag `linewrap`

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

!! Apply Styles to In-line Text

* Start a text block with @,,,,@ and the CSS styles with no spaces

Sample Code:

```
@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line
```

<<<
Result:

```
These are
separate lines
here

This is one big line
```
<<<

* or start in the middle of a text block

Sample Code:

```
This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.
```

<<<
Result:

```
This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.
```
<<<

TotalCommander

<<glbl_article_list>>

TotalCommander\Create new Text File

"""
[Total Commander directory]
- [Top of the directory]
- Hold down on the '..' button to see the menu -> Opens menu
- - or Hold down on any subdirectory name to see the menu -> Opens menu

- [context menu]
- Click option New Text file -> Opens dialog

- [Create new text file dialog]
- Enter a new text file name
- Click button OK -> Closes dialog

- [Directory list]
- Note: The new file was added to the current folder

TotalCommander\Local file desktop shortcut

"""
Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Total Commander directory]
- Hold down on file entry named like *.html -> Opens menu

- [context menu]
- Click option Create link on desktop -> Opens dialog

- [Create link dialog, main page, command line section]
- Click button '>>' -> Opens dialog

- [Choose app dialog, main page]
- Click option Choose app * -> Navigates page

- [Choose app dialog, Choose app * page]
- Click option Chrome -> Navigates page

- [Create link dialog, main page]
- Click button OK / Apply -> Closes dialog

[Android Desktop icons]
- Note: The icon was added to the desktop automatically

TW Project

<<glbl_article_list>>

TW Project\Check app

<<ext "Project Check app">>

Goal: Find food by aisle

TW Project\Code Snapshot

<<ext "TW Snapshot Review">>

Goal: Browse the code inside the WIki file

<<ext "TW Snapshot v5d01d23 main-site">>

<<ext "TW Snapshot v5d01d23 empty">>

<<ext "TW Snapshot v5d01d23 pre-release">>

<<ext "TW Snapshot v5d01d23 update">>

TW Project\Features list

<<ext "TW Features">>

Goal: Demonstrate every Wiki command and option

TW Project\Javascript Plugin instructions

<<ext "TW Create Javascript Plugin">>

TW Project\Shuffle List addon

<<ext "Shuffle List Entries">>

TW Project\Text Replace addon

<<ext "TW Addon Text Replace">>

Goal: Add text replacement functionality to the standard TWCard editor

TW Project\TiddlyWiki Manual

<<ext "TW Manual">>

Goal: Explain the Single-Page Quine Wiki architecture

TW Project\TW JS Pretty

<<ext "TW JS Pretty">>

Goal: Upload a text file and comment on each line, table or function

TW Project\Wiki Empty Setup

<<ext "Empty Wiki Setup">>

Goal: Use the empty TW document and generate a static HTML page

Unicode

<<glbl_article_list>>

Unicode\Code Blocks

<<ext "Unicode Block 00-Basic Latin">>

<<ext "Unicode Block 01-Latin Supplement">>

<<ext "Unicode Code Block List">>

<<ext "Unicode Block Planes">>

Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)

Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)

Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)

Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

Unicode\Latest Version

<<ext "Unicode Character Database">>

All files for the most up-to-date version of the Unicode Character Database can be found at: http://www.unicode.org/Public/UCD/latest/.

The latest text file databases are at https://www.unicode.org/Public/UCD/latest/ucd/. The latest set of text file databases is in a ZIP file at https://www.unicode.org/Public/UCD/latest/ucd/UCD.zip.

The list of Unicode Code Blocks are in the text database https://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt.

There is a list of names for the Unicode Code Points at https://www.unicode.org/Public/UCD/latest/ucd/Index.txt. There same list is sorted in Code Point order at https://www.unicode.org/Public/UCD/latest/ucd/NameAliases.txt. Each hex code can have multiple names.

The unique list of Unicode Code Points is at https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt. There is a character name and possibly an alternative name on each row.


VBNetCode

<<glbl_article_list>>

VBNetCode\Application Startup require DLLs

```
Option Strict On
Namespace My
    Partial Friend Class MyApplication
        Sub Main(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
            Mx.Want.TestReferencedAssemblies_errhnd(e)
            'Next goes to frmInput_1_Load, then Want.Compile_And_Run_Script
        End Sub
    End Class
End Namespace

Namespace Mx
    Partial Public Class Want
        Public Shared Sub TestReferencedAssemblies_errhnd(ur_startup_event_args As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs)
            Dim objERR_LIST = New ErrListBase : Try
                Call Assistant.TestReferencedAssemblies()

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                MsgBox(objERR_LIST.ToString, , My.Application.Info.Title)
                ur_startup_event_args.Cancel = True
            End If
        End Sub 'TestReferencedAssemblies_errhnd
    End Class 'Want
    
    Partial Public Class Assistant
        Public Shared Sub TestReferencedAssemblies()
            'Will error if DLL does is not available
            Dim objV1 = System.Data.SqlClient.SortOrder.Ascending
        End Sub 'TestReferencedAssemblies
    End Class 'Assistant
End Namespace 'Mx

VBNetCode\Checksum calculate

I want a .Net program to calculate the SHA512 hash of a file

```
Dim strHASH_KEY = ""
Using objSHA = New System.Security.Cryptography.SHA512Managed
    Using stmFILE = System.IO.File.OpenRead(flnDATA)
        strHASH_KEY = "[" & System.BitConverter.ToString(objSHA.ComputeHash(stmFILE)).Replace("-", "").ToLower & "]"
        'Convert.ToBase64String(
    End Using
End Using

VBNetCode\Copy File Lines

```
Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), bolAPPEND_FILE, gUTF8_FileEncoding)
	Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
		While stmDATA.EndOfStream = False
			'Character copy
			Dim intENTRY = stmDATA.Read()
			Dim strENTRY = ChrW(intENTRY)
			stmOUT_FILE.Write(strENTRY)
			
			'Line copy
			Dim strLINE = stmDATA.ReadLine()
			stmOUT_FILE.WriteLine(strLINE)
		End While 'stmDATA
	End Using 'stmDATA
End Using 'stmOUT_FILE
```

Split File into chunks of 100,000 lines each

```
Dim intFILE_COUNT = 0
Dim intLINE_COUNT = 0
Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
	While stmDATA.EndOfStream = False
		intFILE_COUNT += 1
		intLINE_COUNT = 0
		Dim strFILE_COUNT = intFILE_COUNT.ToString()
		If Len(strFILE_COUNT) = 2 Then
			strFILE_COUNT = "c" & strFILE_COUNT
		ElseIf Len(strFILE_COUNT) = 3 Then
			strFILE_COUNT = "d" & strFILE_COUNT
			
			End If 'strFILE_COUNT
		
		strFILE_COUNT = "e" & strFILE_COUNT
		Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT(strFILE_COUNT & ".TXT"), False, gUTF8_FileEncoding)
			While stmDATA.EndOfStream = False
				Dim strLINE = stmDATA.ReadLine()
				stmOUT_FILE.WriteLine(strLINE)
				intLINE_COUNT += 1
				
				If intLINE_COUNT >= 100000 Then
					Exit While
					
					End If
				
				End While 'stmDATA
			
			End Using 'stmOUT_FILE

		End While 'stmDATA
	
	End Using 'stmDATA

VBNetCode\DotNet Core Compile EXE

[https://github.com/dotnet/core/issues/5409]

<<<
In .NET 5 the single-file publish may produce more than one file and it's by design. See the expected behavior described here: 

https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md#user-experience

In 3.1 single-file is basically just a self-extracting executable - it writes everything into temp and runs from there. As such for the running app nothing really changes (everything is a file, with a path and so on).

In 5 we don't write to disk by default, all managed assemblies are loaded directly from the executable. The problem is native libraries - it's technically VERY difficult to include a random .dll in an executable and run it from the executable directly.

If you only take the .exe and run it, it won't work - it needs those additional files.

If you need .NET 5 but want the self-extracting behavior you can set IncludeAllContentForSelfExtract=true and it will behave basically the same as in 3.1.

There's also a "hybrid" mode IncludeNativeLibrariesForSelfExtract=true which will produce just one executable and that will write the native libraries to temp and then run.
<<<

User-replaced value = UrProjectDir

[UrProjectDir folder]
- Start with [[VBNetCode\DotNet Core New Project]]

"""
[Windows CLI]
- [Compile into an EXE]
- `dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep`
- Text output ->
"""

```
Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  t3 -> UrProjectDir\bin\Release\net5.0\win10-x64\UrProjectDir.dll
  t3 -> UrProjectDir\Dep\
```

"""
[UrProjectDir folder]
- [Look for the new folders]
- New sub-folders: bin, Dep
- Note: The compiled program is in the Dep subfolder named UrProjectDir.exe
- - The UrProjectDir.pdb file is used for debugging purposes and would not normally be deployed with your EXE file

[Windows CLI]
- [Remove the temporary folders in the UrProjectDir]
- `rd bin /s /q`
- `rd obj /s /q`
- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output shows as if you ran the command `dotnet run`

- Note: You can output the `System.AppContext.BaseDirectory` to find the Temp that holds the uncompressed program
"""

"""
[Program.vb file]
- [Replaces lines in Main sub]
- `Console.WriteLine(System.AppContext.BaseDirectory)`

[Windows CLI]
- [Compile into an EXE]
- `dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep`
- Note: If running DotNet Core 3.1,
- - `dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true -p:PublishSingleFile=true`
- -  The "--self-contained" option is incompatible with the "-p:PublishReadyToRun=true" and "-p:PublishSingleFile=true" options

- Note: When you choose the Portable publish option, you'll get a package that is capable of running on either x86 (32-bit) machines and x64 (64-bit) machines
- - The next run would have to JIT compile the application again as it is used
- - The advantage here is that you'd only need to distribute one package, and it'll run on both x86/x64 machines
- - `dotnet publish -c Release -r portable --self-contained`

- [Remove the temporary folders in the UrProjectDir]
- `rd bin /s /q`
- `rd obj /s /q`
- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output =
"""

```
C:\Users\UrUsername\AppData\Local\Temp\.net\UrProjectDir\SomeRandom-8-letters.SomeRandom-3-letters\
```

"""
- Note: This folder gets created on the first run the of UrProjectDir.exe
- - The second run starts faster because the files have already been extracted to this temporary folder
- - You can delete the temporary folder, and running the UrProjectDir.exe will create it again.

- Note: You can specify a different temporary folder by setting the Environment Variable `DOTNET_BUNDLE_EXTRACT_BASE_DIR`

- `SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%USERPROFILE%\Downloads\UrProjectDir\tmp`
- Note: You can set the Environment Variable in a batch file and it will not be saved for new Windows CLI windows.
- - To set it permanently, use `Control Panel` \ `System and Security` \ `System` \ `Advanced systems settings` \ `Advanced` tab \ `Environment Variables` button \ top or bottom section \ `New` button, Variable Name = `DOTNET_BUNDLE_EXTRACT_BASE_DIR`, Variable Value = `UrFullPathToTempDirectory`, `OK button`
- - Trying to use a relative directory path ends up not running the executable

- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output = 
"""

```
C:\Users\UrUsername\Downloads\UrProjectFolder\tmp\UrProjectFolder\SomeRandom-8-letters.SomeRandom-3-letters\
```

"""
- [Review the size of the TMP folder]
- `dir tmp /s`
- Text output = 23 Files, 8 Dirs

- [Remove the temporary directory]
- `rd tmp /s /q`

[UrProjectDir\Dep folder]
- [Create a script to run the project and clean up the temporary files]
- New file = UrProjectDir.cmd

[UrProjectDir.cmd file]
"""

```
@@ECHO OFF
SET CUR_DIR=%~dp0
SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%CUR_DIR%tmp
"%CUR_DIR%UrProjectDir.exe"
rd "%CUR_DIR%bin" /s /q 2> nul
rd "%CUR_DIR%obj" /s /q 2> nul
rd "%CUR_DIR%tmp" /s /q 2> nul
```

"""
[Windows CLI]
- [Run the clean-execution script]
- `Dep\UrProjectDir.cmd`
- Note: There is no tmp subfolder

VBNetCode\DotNet Core Installation using Binaries

"""
[https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net50]
"""

<<<
As an alternative to the Windows installers for .NET, you can download and manually install the SDK or runtime. Manual install is usually performed as part of continuous integration testing. For a developer or user, it's generally better to use an installer.

Both .NET SDK and .NET Runtime can be manually installed after they've been downloaded. If you install .NET SDK, you don't need to install the corresponding runtime. First, download a binary release for either the SDK or the runtime from one of the following sites:

https://dotnet.microsoft.com/download/dotnet/5.0

https://dotnet.microsoft.com/download/dotnet-core

Create a directory to extract .NET to, for example %USERPROFILE%\dotnet. Then, extract the downloaded zip file into that directory.

By default, .NET CLI commands and apps won't use .NET installed in this way and you must explicitly choose to use it. To do so, change the environment variables with which an application is started:

```
set DOTNET_ROOT=%USERPROFILE%\dotnet
set PATH=%USERPROFILE%\dotnet;%PATH%
set DOTNET_MULTILEVEL_LOOKUP=0
```

This approach lets you install multiple versions into separate locations, then explicitly choose which install location an application should use by running the application with environment variables pointing at that location.

When DOTNET_MULTILEVEL_LOOKUP is set to 0, .NET ignores any globally installed .NET version. Remove that environment setting to let .NET consider the default global install location when selecting the best framework for running the application. The default is typically C:\Program Files\dotnet, which is where the installers install .NET.
<<<

"""
[https://docs.microsoft.com/en-us/dotnet/core/install/how-to-detect-installed-versions?pivots=os-windows]
"""

<<<
When you install .NET from an installer or script, it's installed to a standard folder. Much of the time the installer or script you're using to install .NET gives you an option to install to a different folder. If you choose to install to a different folder, adjust the start of the folder path.

dotnet executable in C:\program files\dotnet\dotnet.exe

.NET SDK in C:\program files\dotnet\sdk\{version}\

.NET Runtime in C:\program files\dotnet\shared\{runtime-type}\{version}\
<<<

VBNetCode\DotNet Core Installed Path

"""
[Windows CLI]
- [Run the system information report]
- `dotnet --info`
"""

```
.NET Core SDK (reflecting any global.json):
 Version:   3.1.401
 Commit:    5b6f5e5005

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18363
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.401\

Host (useful for support):
  Version: 3.1.7
  Commit:  fcfdef8d6b

.NET Core SDKs installed:
  3.1.301 [C:\Program Files\dotnet\sdk]
  3.1.401 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
```

VBNetCode\DotNet Core New Project

[https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new]

<<<
You can run dotnet new --list or dotnet new -l to see a list of all installed templates. If the TEMPLATE value isn't an exact match on text in the Templates or Short Name column from the returned table, a substring match is performed on those two columns.

Starting with .NET Core 3.0 SDK, the CLI searches for templates in NuGet.org when you invoke the dotnet new command in the following conditions:

* If the CLI can't find a template match when invoking dotnet new, not even partial.
* If there's a newer version of the template available. In this case, the project or artifact is created but the CLI warns you about an updated version of the template.
<<<

[https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli]

"""
User-replaced value = UrProjectDir

[Windows CLI]
- [Navigate to the User Downloads folder]
- `cd %USERPROFILE%\Downloads`
- [Create a new DotNet Core project named UrProjectDir]
- `dotnet new console -lang VB -o UrProjectDir`
- Text output =
"""

```
Getting ready...
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj...
  Determining projects to restore...
  Restored C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj (in 65 ms).
Restore succeeded.
```

"""
- [Navigate to the new UrProjectDir]
- `cd UrProjectDir`

[UrProjectDir folder]
- [Look for the new files and folders]
- New files: UrProjectDir.vbproj and Program.vb
- New sub-folder: obj

[Windows CLI]
- [Download a dependency]
- `dotnet add package Figgle`
- Text output =
"""

```
  Determining projects to restore...
  Writing C:\Users\Dad\AppData\Local\Temp\tmpE018.tmp
info : Adding PackageReference for package 'Figgle' into project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info :   GET https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json
info :   OK https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json 104ms
info : Restoring packages for C:\Users\Dad\Downloads\t3\t3.vbproj...

info : Installing runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple 4.3.0.
info : Installing runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl 4.3.0.

info : Package 'Figgle' is compatible with all the specified frameworks in project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : PackageReference for package 'Figgle' version '0.4.0' added to file 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : Committing restore...
info : Writing assets file to disk. Path: C:\Users\Dad\Downloads\t3\obj\project.assets.json
log  : Restored C:\Users\Dad\Downloads\t3\t3.vbproj (in 8.04 sec).
```

"""
[Program.vb file]
- [Replace lines in Main sub]
- `Console.WriteLine(Figgle.FiggleFonts.Standard.Render("Hello, World!"))`

[Windows CLI]
- [Compile into an EXE and run it]
- `dotnet run`
- If you did not enter the program line incorrectly, Text output =
"""

```
Program.vb(5,79): error BC30037: Character is not valid.

The build failed. Fix the build errors and run again.
```

"""
- If you entered the program line correctly, Text output shows Hello World in a large font
"""

VBNetCode\DotNetCore Installation using Installer

"""
[https://dotnet.microsoft.com/platform/support/policy/dotnet-core]
- 2020m11d24: .NET 5 is the current version of DotNet Core. It was released on November 10, 2020.

[https://dotnet.microsoft.com/download/dotnet-core]
- [Supported versions, record Version = .NET 5.0]
- Click link .NET 5.0 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/5.0]
- [record Release Information = v5.0.0, Build Apps column]
- [SDK grid, record OS = Windows]
- Click link x86 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-windows-x64-installer]
- Auto-download started -> Saves file

[Local Computer Downloads folder]
- [filename = dotnet-sdk-5.0.100-win-x64.exe]
- Run program -> Opens form

[Microsoft .NET SDK 5.0.100 (x64) Installer window]
- Click button Install -> Windows dialog
- Question: Do you want to allow the program to make changes to your computer?
- Click button Yes -> Closes dialog
- Wait for progress bar to complete -> Navigates page
- Note: Installation was successful
- Click button Close -> Closes window

[[VBNetCode\DotNet Core Installed Path]]

VBNetCode\File Exists

```
Dim bolFILE_EXISTS = System.IO.File.Exists(flnDATA)

VBNetCode\File Size

```
Dim sioFILE = New System.IO.FileInfo(flnDATA)
Dim intFILE_SIZE = sioFILE.Length

VBNetCode\Global functions passed as Classes

```
    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

VBNetCode\In-Memory Compile

```
Namespace Mx
    Public Class ScriptRun
        ' Build a Hello World program graph using 
        ' System.CodeDom types.
        Public Class enmC_V_J
            Inherits bitBASE
            Public Shared CSharp As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared VisualBasic As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared JScript As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
        End Class 'enmC_V_J

        Public Shared Function RunCode(ur_provider As Mx.ScriptRun.enmC_V_J, ur_input_script As String, ur_assembly_folder As String) As String
            Dim strSOURCE_CODE = ur_input_script
            Dim stpERR_MSG = Strapd()
            Dim stpCODE_FILE = Strapd()
            ' Configure a CompilerParameters that links System.dll and produces the specified executable file.
            Dim objAPP_DOMAIN As AppDomain = Nothing
            Dim objCOMPILE_RUNNER As CompilerRunner = Nothing
            Dim objCOMPILER_PARM = New System.CodeDom.Compiler.CompilerParameters
            Dim objCOPMILER_RESULT As System.CodeDom.Compiler.CompilerResults = Nothing
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing

            If stpERR_MSG.Length = 0 Then
                'objAPP_DOMAIN = System.AppDomain.CreateDomain("MyDomain", AppDomain.CurrentDomain.Evidence, CreateSetup())
                'objCOMPILE_RUNNER = objAPP_DOMAIN.CreateInstanceFromAndUnwrap(GetType(CompilerRunner).Assembly.Location, GetType(CompilerRunner).FullName)
                objCOMPILE_RUNNER = New Mx.CompilerRunner
                stpERR_MSG.d(objCOMPILE_RUNNER.Compile(stpCODE_FILE.ToString, ur_provider.name, objCOMPILER_PARM))
            End If

            If stpERR_MSG.Length = 0 Then
                stpERR_MSG.d(objCOMPILE_RUNNER.Run("Mx.Class1", "RetVal"))
            End If

            If objAPP_DOMAIN IsNot Nothing Then
                'AppDomain.Unload(objAPP_DOMAIN)
            End If
            ' Return the results of compilation.
            Return stpERR_MSG.ToString
        End Function 'RunCode

        Public Shared Function CreateSetup() As AppDomainSetup
            Dim retSETUP = New AppDomainSetup
            With retSETUP
                .ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
                .ApplicationName = "TestDLL"
                .DisallowBindingRedirects = False
                .ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
                .LoaderOptimization = LoaderOptimization.MultiDomainHost
            End With
            CreateSetup = retSETUP
        End Function 'CreateSetup
    End Class 'ScriptRun

    Public Class CompilerRunner
        Inherits MarshalByRefObject

        Public cur_assembly As System.Reflection.Assembly = Nothing
        'AppDomain.CurrentDomain.FriendlyName = MyDomain

        Public Function Compile(ur_code As String, ur_provider As String, ur_compiler_parm As System.CodeDom.Compiler.CompilerParameters) As String
            Dim stpERR_MSG = Strapd()
            Me.cur_assembly = Nothing
            Dim provider As System.CodeDom.Compiler.CodeDomProvider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider(ur_provider) 'New Microsoft.VisualBasic.VBCodeProvider 
            Dim objCOMPILER_RESULT = provider.CompileAssemblyFromSource(ur_compiler_parm, ur_code) ' Strapd().d("Namespace Mx").dLine("Public Class Class1").dLine("Public Shared Function RetVal() As String").dLine("RetVal=""Hi""").dLine("End Function").dLine("End Class").dLine("End Namespace"))
            If objCOMPILER_RESULT.Errors.Count = 0 Then
                Me.cur_assembly = objCOMPILER_RESULT.CompiledAssembly

            Else
                stpERR_MSG.dLine("Compile Errors")
                stpERR_MSG.dLine()
                For Each errItem As System.CodeDom.Compiler.CompilerError In objCOMPILER_RESULT.Errors
                    stpERR_MSG.dLine(errItem.ErrorText & " [" & errItem.Line + 5 & "]")
                    stpERR_MSG.dLine()
                    stpERR_MSG.dLine()
                Next errItem

                stpERR_MSG.dLine(ur_code)
            End If 'objCOMPILER_RESULT

            Compile = stpERR_MSG.ToString
        End Function 'Comiple

        Public Function Run(ur_type_name As String, ur_method_name As String) As String
            Dim stpERR_MSG = Strapd()
            Dim t As System.Type = Me.cur_assembly.CreateInstance(ur_type_name).GetType()
            'Dim objRESULT = t.InvokeMember(ur_method_name, System.Reflection.BindingFlags.InvokeMethod, Nothing, Me.cur_assembly, {})
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing
            For Each m As System.Reflection.MethodInfo In t.GetMethods
                If m.Name = ur_method_name Then
                    objMETHOD_MAIN = m
                    Exit For
                End If
            Next m

            If objMETHOD_MAIN IsNot Nothing Then
                Dim objRESULT = objMETHOD_MAIN.Invoke(Nothing, Nothing)
                If objRESULT IsNot Nothing Then
                    stpERR_MSG.dLine(objRESULT.ToString)
                End If 'objRESULT
            End If 'objMETHOD_MAIN

            Run = stpERR_MSG.ToString
        End Function 'Run
    End Class 'CompileRunner
End Namespace 'Mx

VBNetCode\Send Keys

Send one alt-tab

```
System.Windows.Forms.SendKeys.Send("%{TAB}")
```

Hold down Alt, press alt-tab twice, and release Alt

```
System.Windows.Forms.SendKeys.Send("%({TAB}{TAB})")
```

The Windows key is not so easy to emulate.
- Auto-It or Auto-Hotkey can do more complicated patterns
- VB.Net can use PInvoke to have more capabilities

VBNetCode\Text file to JSON Lines

This outputs a file that can be dragged into TiddlyWiki.

```
<$list variable=cur_char filter="[[UrPK]get[text]splitregexp[\n]join[]split[]each:value[]!match[ ]sort[]]">
<<cur_char>>:
<$list variable=disp_name filter="[[Unicode Char Names]getindex<cur_char>else[missing]]">
<<disp_name>>
</$list><!--disp_name-->
<br>
</$list><!--cur_char-->

[[Unicode Char Names]]
```


```
Dim strFILE_PATH = "UnicodeData.txt"
Dim strOUT_PATH = strFILE_PATH & ".json"
Using stmOUT_FILE = New System.IO.StreamWriter(strOUT_PATH)
	Dim qs = """"
	Dim strESC_DQT = "\" & qs
	stmOUT_FILE.Write("[{""created"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & ",""modified"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & "," &
		qs & "title" & qs & ":" & qs & "Unicode Char Names" & qs & ",""type"":""application/json"",""text"":""{")
	Using stmDATA = New System.IO.StreamReader(strFILE_PATH)
		Dim LINCTR = 0
		While stmDATA.EndOfStream = False
			Dim strLINE = stmDATA.ReadLine()
			Dim intFOUND_SPRTR = InStr(strLINE, ";")
			
			Dim strHEX = Mid(strLINE, 1, intFOUND_SPRTR - 1)
			Dim intCHAR = Cint("&H" & strHEX)
			Dim strCHAR = UCase(strHEX)
			Dim strPREFIX = Left(strCHAR, 2)
			If Len(strCHAR) <> 4 Then
				strPREFIX = ""
			End If
			
			If intCHAR < 32 Then
			  strCHAR = ""
			ElseIf intCHAR > 65534 OrElse
			  strPREFIX = "D8" OrElse
			  strPREFIX = "D9" OrElse
			  strPREFIX = "DA" OrElse
			  strPREFIX = "DB" OrElse
			  strPREFIX = "DC" OrElse
			  strPREFIX = "DD" OrElse
			  strPREFIX = "DE" OrElse
			  strPREFIX = "DF" Then
				strCHAR = "\u" & strHEX
			Else
				strCHAR = CHRW(intCHAR)
				If strCHAR = "\" Then
					strCHAR = "\\\\"
				ElseIf strCHAR = """" Then
					strCHAR = "\\\" & """"
				End If
			End If

			If strCHAR <> "" Then
				LINCTR += 1
				If LINCTR > 1 Then
					stmOUT_FILE.Write(",")
				End If
				stmOUT_FILE.Write("\n    " & strESC_DQT & strCHAR & strESC_DQT & ":" & " " & strESC_DQT & strLINE.Replace("\", "\\").Replace(Chr(10), "\n").Replace(qs, strESC_DQT).Replace("<", "&lt;") & strESC_DQT)
			End If
		End While 'stmDATA
	End Using 'stmDATA
	
	stmOUT_FILE.Write("\n}" & qs & "}]")
End Using 'stmOUT_FILE

VBNetCode\To Hex

"""
Change string with numbers (0 to 9) and/or letters (a-f) into decimal number

[q/a page]
- https://stackoverflow.com/questions/642417/how-do-you-convert-hex-to-decimal-using-vb-net

[sample code]
"""

```
Dim strTEXT = "FF"
Dim strHEX_CODE = "&H" & strTEXT
Dim intNUMBER = CInt(strHEX_CODE)
MsgBox(intNUMBER) -> 255

VBNetCode\Unicode Code Point

<<ext "Microsoft DotNet Char ConvertToUTF32">>

* Note: The index can be any character in the string

```
retval = char.ConvertToUtf32(s:="A", index:=0).Tostring
```

<<<
Result:

```
65
```
<<<

VBNetCode\UserBowl example

```
    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As zapp_folder = TRow(Of enmUN).glbl.Trbase(Of zapp_folder).NewBitBase() : Public Class zapp_folder : Inherits enmUN : End Class
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared background_color As zbackground_color = TRow(Of enmUN).glbl.Trbase(Of zbackground_color).NewBitBase() : Public Class zbackground_color : Inherits enmUN : End Class
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_project_code As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared compiler_exe As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared form_title As zform_title = TRow(Of enmUN).glbl.Trbase(Of zform_title).NewBitBase() : Public Class zform_title : Inherits enmUN : End Class
        Public Shared path As zpath = TRow(Of enmUN).glbl.Trbase(Of zpath).NewBitBase() : Public Class zpath : Inherits enmUN : End Class
        Public Shared script_path As zscript_path = TRow(Of enmUN).glbl.Trbase(Of zscript_path).NewBitBase() : Public Class zscript_path : Inherits enmUN : End Class
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared window_status As zwindow_status = TRow(Of enmUN).glbl.Trbase(Of zwindow_status).NewBitBase() : Public Class zwindow_status : Inherits enmUN : End Class
    End Class

    Public Class enmUR_Color
        Inherits bitBASE
        Public Shared Clear As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Green As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Red As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
    End Class

    Public Class enmUR_Status
        Inherits bitBASE
        Public Shared Show As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
        Public Shared Close As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'db.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit(Have.WindowsMsgBox, Have.WindowsCboard)
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)
            Private enrBackground_Color As System.Drawing.Color
            Private enrUR_Color As enmUR_Color

            Public ReadOnly Property Background_Color_of_Form As System.Drawing.Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color_of_Form = Me.enrBackground_Color
                End Get
            End Property 'Background_Color_of_Form

            Public Property Background_Color As enmUR_Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color = Me.enrUR_Color
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As enmUR_Color)
                    Dim intCOLOR = System.Drawing.Color.Transparent
                    If value Is enmUR_Color.Red Then
                        intCOLOR = System.Drawing.Color.Red

                    ElseIf value Is enmUR_Color.Green Then
                        intCOLOR = System.Drawing.Color.Green
                    End If

                    Me.enrBackground_Color = intCOLOR
                    Me.enrUR_Color = value
                    Me.v(enmUB.contents) = value.name
                End Set
            End Property 'Contents

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_bowlname_is(ur_cmp As enmUN) As Boolean
                v_bowlname_is = AreEqual(Me.v(enmUB.bowl_name), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_cmp As enmUR_Color) As Boolean
                v_is = AreEqual(Me.Contents, ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit(ur_windowsmsgbox_env As Have.glblWindowsMsgBox, ur_windowscboard_env As Have.glblWindowsCboard)
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = ur_windowsmsgbox_env.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        ur_windowscboard_env.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Dim strASSEMBLY_EXE = mt
                Try
                    strASSEMBLY_EXE = My.Application.Info.Title
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_FOLDER = FileNamed()
                Try
                    flnASSEMBLY_FOLDER.wAssemblyDir(My.Application.Info)
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_PATH = flnASSEMBLY_FOLDER.gCopy.d(strASSEMBLY_EXE)
                Me.SelKey(enmUN.app_name).Contents = flnASSEMBLY_PATH.FileGroup
                Me.SelKey(enmUN.app_path).Contents = flnASSEMBLY_PATH
                Me.SelKey(enmUN.app_folder).Contents = flnASSEMBLY_FOLDER

                'enmUN.compiler_exe, enmUN.path take the first non-prefixed parameters; they are just file paths but without /parameter_name=
                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText, enmUN.compiler_exe, enmUN.path)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function 'InsFrom_Application

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCboard(ur_hdr As Boolean) As Integer
                ToCboard = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN

VBNetCode\Version

<<ext "WestWindCom Net Core Runtime">>
<<ext "SO.com RunTime Net 4.5">>

```
Function version_info() As String
version_info = "flag CLR 4.5 Features = " & If(Type.GetType(typeName:="System.Reflection.ReflectionContext", throwOnError:=False) Is Nothing, "", "True") & vbCrLf
version_info &= "flag CLR 4.51 Features = " & If(Type.GetType(typeName:="System.Runtime.GCLargeObjectHeapCompactionMode", throwOnError:=False) Is Nothing, "", "True") & vbCrLf
version_info &= "CLR Version = " & System.Environment.Version.ToString & vbCrLf
version_info &= "CLR Local Path = " & System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() & vbCrLf
version_info &= "Operating System = " & CType(System.Attribute.GetCustomAttribute(System.Reflection.Assembly.GetEntryAssembly(), GetType(System.Runtime.Versioning.TargetFrameworkAttribute)), System.Runtime.Versioning.TargetFrameworkAttribute).FrameworkName & " on " & System.Runtime.InteropServices.RuntimeInformation.OSDescription
End Function
```

VBNetProject

<<glbl_article_list>>

VBNetProject\~Clear Local

```
rd /s /q bin
rd /s /q obj
pause

VBNetProject\~Rebiuld Local

```
for %%f in (*.sln) do (
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
	
    for /D %%m in ("C:\Program Files (x86)\MSBuild\*\Bin\MSBuild.exe") do (
        "%%~m" /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
   )
:compile_complete
pause
del ..\Dep\*.exe
move bin\Release\*.exe ..\Dep
rd /s /q bin
rd /s /q obj
pause

VBNetProject\dbUserInputMock

!! Automatically convert the form to the dbUserInput class

```
Partial Public Class frmInput_1
    <System.Diagnostics.DebuggerHidden()>
    Public Shared Widening Operator CType(b As frmInput_1) As Mx.dbUserInput
        Return New Mx.dbUserInput(b, b.txtNotice_Message)
    End Operator
End Class 'frmInput_1
```

!! Setup the mock classes
* Create flat classes that have the desired values

```
Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock
End Namespace 'Mx2
```

* In a copy of the Mx.dbUserInput class, rename every `System.Windows.Forms` reference to `Mx2.Mock`

```
Option Strict On
Namespace Mx
    Public Class componentTextBox
        Private objTEXT_BOX As System.Windows.Forms.TextBox

        Public Sub New(ur_textbox As System.Windows.Forms.TextBox)
            objTEXT_BOX = ur_textbox
        End Sub

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objTEXT_BOX IsNot Nothing Then
                    Text = objTEXT_BOX.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objTEXT_BOX IsNot Nothing Then
                    objTEXT_BOX.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'componentTextBox

    Public Class dbUserInput
        Private objINPUT_FORM As System.Windows.Forms.Form
        Public txtNotice_Message As componentTextBox

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_input_form As System.Windows.Forms.Form, ur_notice_message_textbox As System.Windows.Forms.TextBox)
            objINPUT_FORM = ur_input_form
            Me.txtNotice_Message = New componentTextBox(ur_notice_message_textbox)
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Close()
            If objINPUT_FORM IsNot Nothing Then
                objINPUT_FORM.Close()
            End If
        End Sub

        Public Property BackColor As System.Drawing.Color
            <System.Diagnostics.DebuggerHidden()>
            Get
                BackColor = Nothing
                If objINPUT_FORM IsNot Nothing Then
                    BackColor = objINPUT_FORM.BackColor
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As System.Drawing.Color)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.BackColor = value
                End If
            End Set
        End Property 'BackColor

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objINPUT_FORM IsNot Nothing Then
                    Text = objINPUT_FORM.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'dbUserInput
End Namespace 'Mx
```

!! Create sample data
* Load the mock dbUserInput with the testing state

```
Dim mockTextBox = New Mock.TextBox
Dim mockForm = New Mock.Form
Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
Call Mx.UserAction.Run_Script_errhnd(mockUserInput)
```

* Compare the mock dbUserInput field changes to the expected result state

```
Dim strFOUND_RESULT = mockTextBox.Text
If strFOUND_RESULT = strEXPECTED_RESULT Then
	intPASS_COUNT += 1

Else
	intFAIL_COUNT += 1
	stpMOCK_REPORT.dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`").dLine())
End If 'strFOUND_RESULT
```

VBNetProject\DeveloperSettings

<<ext "DeveloperSettings HTM"">>

<<ext "DeveloperSettings ZIP"">>

VBNetProject\MxBaseEc13

<<ext "MxBase Classes">>

```
Option Strict On
Namespace Mx '2020m01d03
    Public Module ConstVar
        Public Const mt = ""
        Public Const qs = """"
        Public Const qt = "'"
        Public Const s = " "

        <System.Diagnostics.DebuggerHidden()>
        Public Function AreEqual(ur_val As String, ur_cmp As String) As Boolean
            AreEqual = String.Equals(ur_val, ur_cmp, System.StringComparison.CurrentCultureIgnoreCase)
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b0(ur_val As Integer) As Integer
            b0 = ur_val - 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b1(ur_val As Integer) As Integer
            b1 = ur_val + 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function ContainingText(ur_large_text As String, ur_small_text As String) As Boolean
            ContainingText = InStr(ur_large_text, ur_small_text, CompareMethod.Text) > 0
        End Function 'ContainingText
        <System.Diagnostics.DebuggerHidden()>
        Public Function gUTF8_FileEncoding() As System.Text.UTF8Encoding
            gUTF8_FileEncoding = glbl.gUTF8_Encoding
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function EndingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            EndingWithText = AreEqual(Right(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'EndingWithText
        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText(ur_value As String) As Boolean
            HasText = Not String.IsNullOrWhiteSpace(ur_value)
        End Function 'HasText
        <System.Diagnostics.DebuggerHidden()>
        Public Function StartingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            StartingWithText = AreEqual(Left(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'StartingWithText

        <System.Diagnostics.DebuggerHidden()>
        Public Function CmdOutput(ur_exec_path As String, Optional ur_exec_param As String = mt) As String
            Dim objPCS As New System.Diagnostics.Process()
            With 1 : Dim prcINFO = objPCS.StartInfo
                prcINFO.FileName = ur_exec_path
                prcINFO.Arguments = ur_exec_param
                prcINFO.UseShellExecute = False
                prcINFO.RedirectStandardOutput = True
                prcINFO.CreateNoWindow = True
            End With 'prcINFO

            objPCS.Start()
            CmdOutput = objPCS.StandardOutput.ReadToEnd()
            objPCS.WaitForExit()
        End Function 'CmdOutput

        <System.Diagnostics.DebuggerHidden()>
        Public Function FileNamed() As MxText.FileName
            FileNamed = New MxText.FileName
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Strapd() As Strap
            Strapd = New Strap
        End Function

        Public Class glbl
            Private Shared objUTF8_ENCODING As System.Text.UTF8Encoding

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If objUTF8_ENCODING Is Nothing Then
                    objUTF8_ENCODING = New System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier:=False, throwOnInvalidBytes:=True)
                End If
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function gUTF8_Encoding() As System.Text.UTF8Encoding
                Call glbl.Init()
                gUTF8_Encoding = glbl.objUTF8_ENCODING
            End Function
        End Class 'glbl
    End Module 'ConstVar

    Public Class ErrListBase
        Dim pstpNOTICE_MSG As Strap

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            pstpNOTICE_MSG = Strapd()
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Function DoContinue() As Boolean
            DoContinue = (Me.Found = False)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            If pstpNOTICE_MSG.Length > 0 Then
                pstpNOTICE_MSG.dLine().dLine()
            End If

            pstpNOTICE_MSG.dLine(ur_exception.Message)
            pstpNOTICE_MSG.dLine(Strapd().d("Error in @r1.@r2").r1(ur_methodbase.DeclaringType.Name).r2(ur_methodbase.Name).dS("(status: @r1)").r1(ur_procedure_status))
        End Sub 'dError_Data

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Stack(ur_exception As System.Exception)
            Dim hr As Integer = System.Runtime.InteropServices.Marshal.GetHRForException(ur_exception)
            pstpNOTICE_MSG.dLine(ur_exception.GetType.ToString & "(0x" & hr.ToString("X8") & "): " & ur_exception.Message & System.Environment.NewLine & ur_exception.StackTrace & System.Environment.NewLine)
            Dim st = New System.Diagnostics.StackTrace(ur_exception, True)
            For Each objFRAME In st.GetFrames
                If objFRAME.GetFileLineNumber() > 0 Then
                    pstpNOTICE_MSG.dLine("Line:" & objFRAME.GetFileLineNumber() & " Filename: " & System.IO.Path.GetFileName(objFRAME.GetFileName) & System.Environment.NewLine)
                End If
            Next objFRAME
        End Sub 'dError_Stack

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function Found() As Boolean
            Found = (pstpNOTICE_MSG.Length > 0)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = pstpNOTICE_MSG
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Throw_Error_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            Call Me.dError_Data(ur_exception, ur_methodbase, ur_procedure_status)
            Throw New LocalException(mt)
        End Sub 'Throw_Error_Data


        Public Class LocalException
            Inherits System.Exception

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String)
                MyBase.New(message)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String, inner As System.Exception)
                MyBase.New(message, inner)
            End Sub
        End Class 'LocalException
    End Class 'ErrListBase

    Public Class iWrap(Of T)
        Public v As T

        Public Sub New(ur_t As T)
            Me.v = ur_t
        End Sub
    End Class 'iWrap

    Public Class ObaCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Obalist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list As Obalist(Of T) = Nothing)
            Call MyBase.New(prv.TotalItems(ur_list))
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObaCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property v() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObaCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function TotalItems(Optional ur_list As Obalist(Of T) = Nothing) As Integer
                TotalItems = 0
                If ur_list IsNot Nothing Then
                    TotalItems = ur_list.Count
                End If
            End Function 'TotalItems
        End Class 'prv
    End Class 'ObaCTR

    Public Class ObjCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Objlist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_list As Objlist(Of T))
            Call MyBase.New(ur_list.Count)
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObjCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property row() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                row = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObjCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function
    End Class 'ObjCTR

    Public Class Obalist(Of T)
        Private vobjLIST() As T

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list() As T = Nothing)
            Me.vobjLIST = ur_list
        End Sub

        Public ReadOnly Property Count() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Count = Me.vobjLIST.Length
            End Get
        End Property

        Public Property Item(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                Item = Me.vobjLIST(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.vobjLIST(ur_index) = ur_val
            End Set
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function kvp() As ObaCTR(Of T)
            kvp = New ObaCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Obalist

    Public Class Objlist(Of T)
        Inherits System.Collections.Generic.List(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As ObjCTR(Of T)
            kvp = New ObjCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Objlist

    Public Class SDPCTR(Of T As {New})
        Inherits RCTR

        Private vsdpLIST As SdPair(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdplist As SdPair(Of T))
            Call MyBase.New(ur_sdplist.Count)
            Me.vsdpLIST = ur_sdplist
        End Sub

        Public Shadows ReadOnly Property Current() As SDPCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDPCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property l() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = Me.vsdpLIST.l_enm(Me.Indexenm)
            End Get
        End Property

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdpLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDPCTR

    Public Class SdPair(Of T As {New})
        Inherits Sdata
        Private vobjT As System.Collections.Generic.Dictionary(Of String, T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            vobjT = New System.Collections.Generic.Dictionary(Of String, T)
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function d(ur_val As String, ur_link As T) As SdPair(Of T)
            d = Me
            Call Me.Add(ur_val)
            Call vobjT.Add(ur_val, ur_link)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDPCTR(Of T)
            kvp = New SDPCTR(Of T)(Me)
        End Function

        Public Property l(ur_key As String) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = vobjT.Item(ur_key)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(ur_key) = ur_val
            End Set
        End Property

        Public Property l_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_b1 = vobjT.Item(Me.v_b1(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_b1(ur_index)) = ur_val
            End Set
        End Property

        Public Property l_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_enm = vobjT.Item(Me.v_enm(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_enm(ur_index)) = ur_val
            End Set
        End Property
    End Class 'SdPair

    Public Class RCTR
        Private pintMAX_NUM As Integer
        Private pintCUR_NUM As Integer

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(ByVal b As RCTR) As Integer
            Return b.Indexb1
        End Operator 'CType

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_max_num As Integer)
            Me.pintMAX_NUM = ur_max_num
        End Sub

        Public Shadows ReadOnly Property Current() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me.pintCUR_NUM
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function GetEnumerator() As RCTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public ReadOnly Property Indexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexb1 = Me.pintCUR_NUM
            End Get
        End Property

        Public ReadOnly Property Indexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexenm = b0(Me.pintCUR_NUM)
            End Get
        End Property

        Public ReadOnly Property LastIndexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexb1 = Me.pintMAX_NUM
            End Get
        End Property

        Public ReadOnly Property LastIndexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexenm = b0(Me.pintMAX_NUM)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function MoveNext() As Boolean
            MoveNext = (Me.pintCUR_NUM < Me.pintMAX_NUM)
            Me.pintCUR_NUM += 1
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Reset() As RCTR
            Reset = Me
            Me.pintCUR_NUM = 0
        End Function
    End Class 'RCTR

    Public Class SDACTR
        Inherits RCTR

        Private psdaLIST As Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdata As Sdata)
            Call MyBase.New(ur_sdata.Count)
            Me.psdaLIST = ur_sdata
        End Sub

        Public Shadows ReadOnly Property Current() As SDACTR
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDACTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.psdaLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDACTR

    Public Class Sdata
        Inherits System.Collections.Generic.List(Of String)

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_val As String) As Sdata
            d = Me
            Call Me.Add(ur_val)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ParamArray ur_val() As String) As Sdata
            dList = Me
            If ur_val IsNot Nothing Then
                For Each strENTRY In ur_val
                    If strENTRY Is Nothing Then
                        strENTRY = mt
                    End If

                    Call Me.Add(strENTRY)
                Next strENTRY
            End If
        End Function 'dList

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As Sdata
            gCopy = New Sdata().dList(Me.ToArray)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDACTR
            kvp = New SDACTR(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Split(ur_text As String, ur_sprtr As Char) As Sdata
            Dim sdaCMP = New Sdata
            Split = sdaCMP
            For Each strTEXT In ur_text.Split(ur_sprtr)
                sdaCMP.Add(strTEXT)
            Next
        End Function 'Split

        Public Property v_b1(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property v_enm(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Sdata

    Public Class Strap
        Private pstbTEXT As System.Text.StringBuilder

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            Me.pstbTEXT = New System.Text.StringBuilder
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(b As Strap) As String
            Return b.ToString
        End Operator

        <System.Diagnostics.DebuggerHidden()>
        Public Function Clear() As Strap
            Clear = Me
            Call Me.pstbTEXT.Clear()
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_text As String) As Strap
            d = Me.dSprtr(mt, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSV_Quoted(ur_index_b1 As Integer, ur_text As String) As Strap
            dCSV_Quoted = Me
            If ur_index_b1 > 1 Then
                Me.d(",")
            End If

            Me.d(qs).d(ur_text.Replace(qs, qs & qs)).d(qs)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ur_sprtr As String, ParamArray ur_text() As String) As Strap
            dList = Me
            If ur_text IsNot Nothing Then
                For Each strENTRY In ur_text
                    Call Me.dSprtr(ur_sprtr, strENTRY)
                Next strENTRY
            End If
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSVList(ParamArray ur_text() As String) As Strap
            dCSVList = Me
            If ur_text IsNot Nothing Then
                For ENTCTR = 0 To UBound(ur_text)
                    Me.dCSV_Quoted(ENTCTR + 1, ur_text(ENTCTR))
                Next ENTCTR
            End If
        End Function 'dCSVList

        <System.Diagnostics.DebuggerHidden()>
        Public Function dLine(Optional ur_text As String = "") As Strap
            dLine = Me.dSprtr(vbCrLf, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dS(ur_text As String) As Strap
            dS = Me.dSprtr(s, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dSprtr(ur_sprtr As String, ur_text As String) As Strap
            dSprtr = Me
            Me.pstbTEXT.Append(ur_sprtr).Append(ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function gCopy(ur_text As String) As Strap
            gCopy = New Strap().d(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText() As Boolean
            HasText = (Me.Length > 0)
        End Function

        Public ReadOnly Property Length As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Length = Me.pstbTEXT.Length
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function r1(ur_text As String) As Strap
            r1 = Me
            Call Me.pstbTEXT.Replace("@r1", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function r2(ur_text As String) As Strap
            r2 = Me
            Call Me.pstbTEXT.Replace("@r2", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function rx(ur_index As Integer, ur_text As String) As Strap
            rx = Me
            Call Me.pstbTEXT.Replace("@r" & ur_index, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = Me.pstbTEXT.ToString
        End Function
    End Class 'Strap

    Public Class bitBASE
        Public name As String
        Public seq As Integer
    End Class

    Public Class TRow(Of T As {New, bitBASE})
        Inherits Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            For Each intVAL In Me.RefColNames
                Me.Add(mt)
            Next
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Index_TableSplit(ur_table As Objlist(Of TRow(Of T)), ur_key As T) As SdPair(Of Objlist(Of TRow(Of T)))
            Dim sdpRET = New SdPair(Of Objlist(Of TRow(Of T)))
            Index_TableSplit = sdpRET
            Dim tblCHUNK As Objlist(Of TRow(Of T)) = Nothing
            For Each rowCHUNK In ur_table
                Dim strINDEX = rowCHUNK.v(ur_key)
                Dim intFOUND = sdpRET.IndexOf(strINDEX)
                If intFOUND < 0 Then
                    tblCHUNK = New Objlist(Of TRow(Of T))
                    sdpRET.d(strINDEX, tblCHUNK)
                Else
                    tblCHUNK = sdpRET.l_enm(intFOUND)
                End If

                tblCHUNK.Add(rowCHUNK)
            Next rowCHUNK

            Call sdpRET.Sort()
        End Function 'Index_TableSplit


        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As TRow(Of T)
            Dim sdaRET = New TRow(Of T)
            gCopy = sdaRET
            For Each kvpENTRY In Me.kvp
                sdaRET.v_enm(kvpENTRY.Indexenm) = kvpENTRY.v
            Next kvpENTRY
        End Function

        Public Function Link_Table(ur_table As Objlist(Of TRow(Of T)), ParamArray ur_key_list() As T) As Objlist(Of TRow(Of T))
            Dim tblRET = New Objlist(Of TRow(Of T))
            Link_Table = tblRET
            For Each rowCHUNK In ur_table
                Dim bolFOUND = True
                For Each intKEY In ur_key_list
                    If AreEqual(rowCHUNK.v(intKEY), Me.v(intKEY)) = False Then
                        bolFOUND = False
                        Exit For
                    End If
                Next intKEY

                If bolFOUND Then
                    tblRET.Add(rowCHUNK)
                End If
            Next rowCHUNK
        End Function 'Link_Table

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function PersistRead(ur_persist_path As String) As Objlist(Of TRow(Of T))
            Dim ttbRET = New Objlist(Of TRow(Of T))
            PersistRead = ttbRET
            If Mx.glbl.gWindowsFS.HasFile(ur_persist_path) Then
                Dim bolFIRST_LINE = True
                Dim lstREF_COL = New Objlist(Of T)
                Using stmIN_FILE = Mx.glbl.gWindowsFS.ReadStream(ur_persist_path)
                    Dim strLINE = mt
                    While stmIN_FILE.EndOfStream = False
                        strLINE &= stmIN_FILE.ReadLine
                        Dim bolBALANCED_QUOTES = True
                        For CHRCTR = 0 To strLINE.Length - 1
                            If strLINE(CHRCTR) = """"c Then
                                bolBALANCED_QUOTES = Not bolBALANCED_QUOTES
                            End If
                        Next CHRCTR

                        If bolBALANCED_QUOTES = False Then
                            strLINE &= vbCrLf

                        Else
                            Dim new_row = New TRow(Of T)
                            If Left(strLINE, 1) = vbLf Then
                                strLINE = Mid(strLINE, 2)
                            End If

                            If bolFIRST_LINE = True Then
                                bolFIRST_LINE = False
                                Dim bolCOL_MATCH = False
                                Dim sdaFIRST_ROW = MxText.CSVSplit(strLINE, vbTab)
                                For Each strENTRY In MxText.CSVSplit(strLINE, vbTab)
                                    Dim enmFOUND_KEY As T = Nothing
                                    For Each enmKEY In new_row.RefColKeys
                                        If AreEqual(enmKEY.name, strENTRY) Then
                                            enmFOUND_KEY = enmKEY
                                            bolCOL_MATCH = True
                                            Exit For
                                        End If
                                    Next enmKEY

                                    lstREF_COL.Add(enmFOUND_KEY)
                                Next strENTRY

                                If bolCOL_MATCH = False Then
                                    Exit While
                                End If

                            ElseIf HasText(strLINE) Then
                                For Each kvpCOL In MxText.CSVSplit(strLINE, vbTab).kvp
                                    Dim enmKEY = lstREF_COL.Item(kvpCOL.Indexenm)
                                    If enmKEY IsNot Nothing Then
                                        new_row.v(enmKEY) = kvpCOL.v
                                    End If
                                Next kvpCOL

                                ttbRET.Add(new_row)
                            End If 'bolFIRST_LINE

                            strLINE = mt
                        End If 'bolBALANCED_QUOTES
                    End While
                End Using 'stmIN_FILE
            End If 'ur_persist_path
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Sub PersistWrite(ur_table As Objlist(Of TRow(Of T)), ur_persist_path As MxText.FileName)
            If Mx.glbl.gWindowsFS.HasDir(ur_persist_path.gParentDir) = False Then
                Mx.glbl.gWindowsFS.CreateDirectory(ur_persist_path.gParentDir)
            End If

            Using stmOUT_FILE = Mx.glbl.gWindowsFS.WriteStream(ur_persist_path)
                For Each kvpROW In ur_table.kvp
                    stmOUT_FILE.Write(kvpROW.row.ToString(kvpROW.Indexb1 = 1, True))
                Next
            End Using 'stmOUT_FILE
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeys() As Objlist(Of T)
            RefColKeys = TRow(Of T).glbl.RefKeys
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeySearch(ur_name As String) As Objlist(Of T)
            RefColKeySearch = TRow(Of T).glbl.RefKeySearch(ur_name)
        End Function 'RefColKeySearch

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColNames() As Sdata
            RefColNames = TRow(Of T).glbl.RefNames
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ToCbrd(ur_hdr As Boolean) As Integer
            ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean, Optional ur_quoted As Boolean = False) As Strap
            Dim stpRET = New Strap
            ToString = stpRET
            If ur_hdr Then : For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : stpRET.d(kvpCOL.v) : Next kvpCOL : stpRET.dLine() : End If
            For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : If ur_quoted Then : stpRET.d(qs).d(Me.v_enm(kvpCOL.Indexenm).Replace(qs, qs & qs)).d(qs) : Else : stpRET.d(Me.v_enm(kvpCOL.Indexenm)) : End If : Next kvpCOL : stpRET.dLine()
        End Function


        Public Property v(ur_cl As T) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.Item(ur_cl.seq)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = ""
                End If

                Me.Item(ur_cl.seq) = ur_val
            End Set
        End Property

        Public Class glbl
            Private Shared sdaTCOL_NAME As Sdata
            Private Shared sdjTCOL_KEY As Objlist(Of T)

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME Is Nothing Then
                    Dim objTEST = GetType(T).GetFields()(0).GetValue(Nothing)
                End If

                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME IsNot Nothing Then
                    sdjTCOL_KEY = New Objlist(Of T)
                    Dim tpeCMP = GetType(T)
                    For Each kvpCOL In sdaTCOL_NAME.kvp
                        For Each objPROP In tpeCMP.GetFields()
                            If tpeCMP.DeclaringType Is tpeCMP Then
                                Dim objBIT = DirectCast(objPROP.GetValue(Nothing), bitBASE)
                                If objBIT.seq = kvpCOL.Indexenm Then
                                    sdjTCOL_KEY.Add(DirectCast(objPROP.GetValue(Nothing), T))
                                    Exit For
                                End If
                            End If 'tpeCMP
                        Next objPROP
                    Next kvpCOL
                End If 'sdaTCOL_NAME
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Function NewProp() As T
                Dim objRET = New T
                NewProp = objRET

                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Function 'NewProp

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub NewProp(ur_prop As T)
                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function NewBitBase() As T
                NewBitBase = glbl.NewProp()
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub NewBitBase(ur_prop As T)
                Call glbl.NewProp(ur_prop)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeys() As Objlist(Of T)
                Call glbl.Init()
                RefKeys = glbl.sdjTCOL_KEY
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeySearch(ur_name As String) As Objlist(Of T)
                Call glbl.Init()
                Dim ttbRET = New Objlist(Of T)
                RefKeySearch = ttbRET
                Dim intFOUND_INDEX = TRow(Of T).glbl.RefNames.IndexOf(ur_name)
                If intFOUND_INDEX >= b0(1) Then
                    ttbRET.Add(TRow(Of T).glbl.RefKeys(intFOUND_INDEX))
                End If
            End Function 'RefKeySearch

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefNames() As Sdata
                Call glbl.Init()
                RefNames = glbl.sdaTCOL_NAME
            End Function

            Public Class Trbase(Of W As {New, T})
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function NewBitBase() As W
                    Dim objRET = New W
                    NewBitBase = objRET
                    Call TRow(Of T).glbl.NewBitBase(objRET)
                End Function
            End Class 'Trbase
        End Class 'glbl
    End Class 'Trow

    Partial Public Class MxText 'Parse
        Public Class enmCMD_RET
            Inherits bitBASE
            Public Shared eq As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared fslash As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs_end As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared txt As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared unk As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared ws As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
        End Class

        Public Class Cmdline_UB(Of T As {New, bitBASE}, W As {New, bitBASE})
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                CommandLine_UBParm = prv.CommandLine_UBParm(ur_ub_key, ur_ub_val, ur_source_text, ur_default_field_list)
            End Function

            Class sCMDLINE
                Inherits Mx.Objlist(Of TRow(Of enmCMD_RET))

                <System.Diagnostics.DebuggerHidden()>
                Public Overloads Function ToString(ur_hdr As Boolean) As String
                    Dim stpRET = Strapd() : For Each kvpREC In Me.kvp : stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr)) : Next kvpREC : ToString = stpRET
                End Function 'ToString
                <System.Diagnostics.DebuggerHidden()>
                Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                End Function
            End Class 'sCMDLINE

            Class sCMD_RET
                Public ttbUB_PARM As Objlist(Of TRow(Of W))
                Public ttbCMD_PARM As sCMDLINE
            End Class

            Partial Private Class prv
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                    Dim objRET = New sCMD_RET
                    CommandLine_UBParm = objRET
                    objRET.ttbUB_PARM = New Objlist(Of TRow(Of W))
                    objRET.ttbCMD_PARM = New sCMDLINE
                    Dim rowCMD_PARM = New TRow(Of enmCMD_RET)
                    objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                    Dim sdaDEFAULT_PARMNAME = New Sdata
                    Dim sdaDEST_PARMS = TRow(Of T).glbl.RefNames
                    For Each intUN In ur_default_field_list
                        sdaDEFAULT_PARMNAME.d(intUN.name)
                    Next

                    Dim stpCOMPILE = Strapd()
                    Dim intPREV_CHUNK = enmCMD_RET.ws
                    Dim intCHUNK_C = enmCMD_RET.ws
                    For CHRCTR = 0 To ur_source_text.Length - 1
                        Dim chrC = ur_source_text(CHRCTR)
                        intCHUNK_C = gChunkType(chrC)
                        Dim intSPAN = 1
                        For SPNCTR = CHRCTR + 1 To ur_source_text.Length - 1
                            Dim chrS = ur_source_text(SPNCTR)
                            Dim intSPAN_C = gChunkType(chrS)
                            If intSPAN_C IsNot intCHUNK_C OrElse
                              intSPAN_C Is enmCMD_RET.qs Then
                                'Combine all chunks except for escaped quotes
                                intSPAN = SPNCTR - CHRCTR
                                Exit For
                            End If

                            If SPNCTR = ur_source_text.Length - 1 Then
                                intSPAN = SPNCTR + 1 - CHRCTR
                                Exit For
                            End If
                        Next SPNCTR

                        Dim strCHUNK = ur_source_text.Substring(CHRCTR, intSPAN)
                        If intPREV_CHUNK Is enmCMD_RET.ws Then
                            'Have ws, skip compiled ws; wait for fslash or default parm
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'skip compiled fslash
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip ws between parameters

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'compile unquoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = enmCMD_RET.txt
                                stpCOMPILE.Clear.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.fslash Then
                            'Have ws-fslash, compile txt parm name; wait for eq
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'qs between parm name and eq is unk
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq Then
                                'skip compile qe
                                rowCMD_PARM.v(enmCMD_RET.fslash) = stpCOMPILE.ToString
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = enmCMD_RET.eq

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'compile txt into parm name
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.eq Then
                            'Have ws-fslash-eq, skip compile; wait for txt
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'flush parameter as "=true"; start new parameter
                                stpCOMPILE.Clear.d("true")
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted parameter value
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'keep ws in eq

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'skip eq between paramater name and value

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'store param name, compile unquoted parameter value
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.txt Then
                            'Have ws-fslash-eq-txt, compile parm val; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                'Keep fslash and qs in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'Keep eq in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs Then
                            'Have ws-fslash-eq-qs, compile parm val; wait for qs_end
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'Keep fslash in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'hold parameter; skip this qs and look for another escaped qs or flush the parameter
                                intPREV_CHUNK = enmCMD_RET.qs_end

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'Keep ws, eq and txt in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs_end Then
                            'Have ws-fslash-eq-qs-qsend, compile parm val without ending quote; wait for qs or ws
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'qs_end then fslash without ws between is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'keep escaped qs
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'qs_end then ws or txt is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.unk Then
                            'Have unk, skip compile; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip parameter; start new parameter
                                rowCMD_PARM.v(enmCMD_RET.txt) = stpCOMPILE.ToString
                                rowCMD_PARM = New TRow(Of enmCMD_RET)
                                objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If
                        End If

                        CHRCTR += intSPAN - 1

                        If CHRCTR = ur_source_text.Length - 1 Then
                            'On last entry
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse intCHUNK_C Is enmCMD_RET.eq Then
                                'flush default parameter value
                                stpCOMPILE.Clear.d("true")
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs OrElse intCHUNK_C Is enmCMD_RET.txt Then
                                'flush parameter
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip trailing ws
                            End If
                        End If
                    Next CHRCTR
                End Function 'CommandLine_Chunk

                Private Class Flush_Ret
                    Public rowCMD_PARM As TRow(Of enmCMD_RET)
                    Public intPREV_CHUNK As enmCMD_RET
                End Class

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function Flush_Parameter(ur_ub_key As W, ur_ub_val As W, ur_cmdparm_row As TRow(Of enmCMD_RET), ur_parm_val As Strap, ur_new_prevchunk As enmCMD_RET, ur_refname_list As Sdata, ur_objret_arl As sCMD_RET) As Flush_Ret
                    Dim objRET = New Flush_Ret
                    Flush_Parameter = objRET
                    objRET.rowCMD_PARM = New TRow(Of enmCMD_RET)
                    ur_objret_arl.ttbCMD_PARM.Add(objRET.rowCMD_PARM)
                    objRET.intPREV_CHUNK = ur_new_prevchunk
                    'flush parameter
                    ur_cmdparm_row.v(enmCMD_RET.txt) = ur_parm_val
                    Dim intFOUND = ur_refname_list.IndexOf(ur_cmdparm_row.v(enmCMD_RET.fslash).ToLower)
                    If intFOUND >= 0 Then
                        With 1 : Dim sdaROW = New TRow(Of W)
                            sdaROW.v(ur_ub_key) = ur_refname_list.v_enm(intFOUND)
                            sdaROW.v(ur_ub_val) = ur_cmdparm_row.v(enmCMD_RET.txt)
                            ur_objret_arl.ttbUB_PARM.Add(sdaROW)
                        End With

                        'Skip parameter if not found
                    End If

                    ur_parm_val.Clear()
                End Function

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function gChunkType(ur_char As Char) As enmCMD_RET
                    If ur_char = vbCr OrElse
                  ur_char = vbLf OrElse
                  ur_char = " "c OrElse
                  ur_char = vbTab Then
                        gChunkType = enmCMD_RET.ws

                    ElseIf ur_char = "="c OrElse
                  ur_char = ":"c Then
                        gChunkType = enmCMD_RET.eq

                    ElseIf ur_char = "/"c Then
                        gChunkType = enmCMD_RET.fslash

                    ElseIf ur_char = """"c Then
                        gChunkType = enmCMD_RET.qs

                    Else
                        gChunkType = enmCMD_RET.txt
                    End If
                End Function 'gChunkType
            End Class 'prv
        End Class
    End Class 'MxText-Parse

    Partial Public Class MxText
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function CSVSplit(ByVal ur_line As String, Optional ur_separator As String = ",") As Sdata
            Dim sdaCMP = New Sdata
            CSVSplit = sdaCMP
            Dim objARRAY = ur_line.ToCharArray
            Dim objSPRTR = Mid(ur_separator, 1, 1).ToCharArray()(0)
            Dim objESCAPE_QUOTE = """"c

            Const cstSTART = 0
            Const cstESC = 1
            Const cstQS = 2
            Dim intPARSE_STATE = cstSTART
            Dim intLEN = Len(ur_line) - 1
            Dim stpFIELD As New Strap
            For intIX = 0 To intLEN
                Dim objCHR = objARRAY(intIX)
                Select Case intPARSE_STATE
                    Case cstESC
                        stpFIELD.d(objCHR)
                        intPARSE_STATE = cstQS

                    Case cstQS
                        If objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstSTART
                            Dim intNEXT_IX = intIX + 1
                            If intNEXT_IX < intLEN Then
                                If objARRAY(intNEXT_IX) = objESCAPE_QUOTE Then
                                    intPARSE_STATE = cstESC
                                End If 'intNEXT_IX
                            End If 'intNEXT_IX

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR

                    Case cstSTART
                        If objCHR = objSPRTR Then
                            sdaCMP.d(stpFIELD.ToString)
                            Call stpFIELD.Clear()

                        ElseIf objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstQS

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR
                End Select 'intPARSE_STATE
            Next intIX

            sdaCMP.d(stpFIELD)
        End Function 'CSVSplit
    End Class 'MxText-Csv

    Public Class MxText
        Public Class FileName
            Public FilePath As String
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.FilePath = mt
            End Sub 'New
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(ur_path As String)
                Me.FilePath = ur_path
            End Sub 'New

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As FileName) As String
                Return b.FilePath
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As String) As FileName
                Return New FileName(b)
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shadows Function ToString() As String
                ToString = Me.FilePath
            End Function 'ToString

            <System.Diagnostics.DebuggerHidden()>
            Public Function dAppendEXT(ur_ext As String) As FileName
                dAppendEXT = Me
                If ur_ext.StartsWith(".") = False Then
                    ur_ext = "." & ur_ext
                End If

                Me.FilePath &= ur_ext
            End Function 'dAppendEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function d(ur_file_name As String) As FileName
                d = Me
                If HasText(Me.FilePath) Then
                    Me.FilePath = System.IO.Path.Combine(Me.FilePath, ur_file_name)

                Else 'Me
                    Me.FilePath = ur_file_name
                End If 'Me
            End Function 'd

            <System.Diagnostics.DebuggerHidden()>
            Public Function dNowTextYMDHMS(ur_file_name As String, Optional ur_separator As String = "_") As FileName
                dNowTextYMDHMS = Me
                Me.d(ur_file_name & ur_separator & Now().ToString("yyyy\mMM\dddthh\mmm\sss").Replace("P12", "N12").Replace("A12", "A00").ToLower)
            End Function 'dNowTextYMDHMS

            Public Property Ext() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Ext = System.IO.Path.GetExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wEXT(value)
                End Set
            End Property 'Ext

            Public ReadOnly Property ExtAll() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ExtAll = Strapd().dList(mt, Me.ExtList.ToArray)
                End Get
            End Property 'ExtAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function ExtList() As Sdata
                Dim sdaDESC = Sdata.Split(Me.FilePath, "."c)
                ExtList = sdaDESC
                sdaDESC.RemoveAt(0)
                For Each ROWCTR In sdaDESC.kvp
                    sdaDESC.v_b1(ROWCTR) = "." & sdaDESC.v_b1(ROWCTR)
                Next ROWCTR
            End Function 'ExtList

            Public Property FileGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileGroup = System.IO.Path.GetFileNameWithoutExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.Ext
                End Set
            End Property 'FileGroup

            Public Property FileBaseGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileBaseGroup = mt
                    For Each strENTRY In Sdata.Split(Me.Name, "."c)
                        FileBaseGroup = strENTRY
                        Exit For
                    Next
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.ExtAll
                End Set
            End Property 'FileBaseGroup

            <System.Diagnostics.DebuggerHidden()>
            Public Function gCopy() As FileName
                gCopy = New FileName(Me)
            End Function 'gCopy

            <System.Diagnostics.DebuggerHidden()>
            Public Function gFullPath() As FileName
                gFullPath = New FileName(glbl.gWindowsFS.GetFullPath(Me.FilePath))
            End Function 'gFullPath

            <System.Diagnostics.DebuggerHidden()>
            Public Function gParentDir() As FileName
                gParentDir = New FileName(Me.ParentDir)
            End Function 'gParentDir

            Public Property Name() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Name = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If

                    If HasText(strPATH) Then
                        Name = System.IO.Path.GetFileName(strPATH)
                    End If
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wParentDir.d(value)
                End Set
            End Property 'Name

            Public Property ParentDir() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ParentDir = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If 'strPATH

                    If HasText(strPATH) Then
                        ParentDir = System.IO.Path.GetDirectoryName(strPATH)
                    End If 'strPATH
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Dim strFILE_NAME = Me.Name
                    If HasText(value) Then
                        Me.FilePath = System.IO.Path.Combine(value, strFILE_NAME)

                    Else 'value
                        Me.FilePath = strFILE_NAME
                    End If 'value
                End Set
            End Property 'ParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function ParentList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH = Me.PathList
                ParentList = sdaPATH
                sdaPATH.RemoveAt(b0(sdaPATH.Count))
            End Function 'ParentList

            <System.Diagnostics.DebuggerHidden()>
            Public Function PathList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH As New System.Collections.Generic.List(Of FileName)
                PathList = sdaPATH

                Dim sdaDESC = New Objlist(Of FileName)
                sdaDESC.Add(Me.gCopy)
                Dim objREDUCE = Me.gCopy
                Call objREDUCE.wParentDir()
                While HasText(objREDUCE.FilePath)
                    sdaDESC.Add(objREDUCE.gCopy)
                    Call objREDUCE.wParentDir()
                End While 'objREDUCE

                For Each objFILE In sdaDESC
                    sdaPATH.Add(objFILE)
                Next objFILE
            End Function 'PathList

            <System.Diagnostics.DebuggerHidden()>
            Public Function wAssemblyDir(ur_assembly_info As Microsoft.VisualBasic.ApplicationServices.AssemblyInfo) As FileName
                wAssemblyDir = Me
                Me.FilePath = ur_assembly_info.DirectoryPath.Replace("\bin\Debug", mt)
            End Function 'wAssemblyDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wClear() As FileName
                wClear = Me
                Me.FilePath = mt
            End Function 'wClear

            <System.Diagnostics.DebuggerHidden()>
            Public Function wEXT(ur_ext As String) As FileName
                wEXT = Me
                Dim strFILE_NAME = Me.FileGroup
                If Left(ur_ext, 1) <> "." Then
                    ur_ext = "." & ur_ext
                End If 'ur_ext

                Me.wParentDir.d(strFILE_NAME & ur_ext)
            End Function 'wEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function wParentDir() As FileName
                wParentDir = Me
                Me.FilePath = Me.ParentDir
            End Function 'wParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wTempFileName(ur_fs_proxy As Microsoft.VisualBasic.MyServices.FileSystemProxy) As FileName
                wTempFileName = Me
                Me.FilePath = ur_fs_proxy.GetTempFileName
                Call ur_fs_proxy.DeleteFile(Me.FilePath)
            End Function 'wTempFileName
        End Class 'FileName
    End Class 'MxText-FileName

    Partial Public Class glbl
        Public Class gCboard
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Clear()
                Call My.Computer.Clipboard.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetText() As String
                GetText = My.Computer.Clipboard.GetText
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function SetText(ur_text As String) As Integer
                If HasText(ur_text) Then
                    Call My.Computer.Clipboard.SetText(ur_text)
                    SetText = 1 + ur_text.Length - ur_text.Replace(vbLf, mt).Length
                Else
                    Call My.Computer.Clipboard.Clear()
                    SetText = 0
                End If
            End Function 'SetText
        End Class 'gCboard

        Public Class gDiagnostics
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function IsRunningWindow(ur_title As String) As Boolean
                IsRunningWindow = False
                For Each objCUR_PROC In System.Diagnostics.Process.GetProcesses()
                    If objCUR_PROC.MainWindowHandle.ToInt32 <> 0 AndAlso
                      AreEqual(objCUR_PROC.MainWindowTitle, ur_title) Then
                        IsRunningWindow = True
                        Exit For
                    End If
                Next objCUR_PROC
            End Function 'IsRunningWindow

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Read_CommandLineText(ur_exec_path As String, ur_exec_param As String) As String
                Dim prcCOMMAND_LINE = gDiagnostics.Start_CommandLine_Program(ur_exec_path, ur_exec_param)
                Read_CommandLineText = prcCOMMAND_LINE.StandardOutput.ReadToEnd()
                prcCOMMAND_LINE.WaitForExit()
            End Function 'Read_CommandLineText

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Start_CommandLine_Program(ur_exec_path As String, ur_exec_param As String) As System.Diagnostics.Process
                Dim retPROCESS As New System.Diagnostics.Process()
                Start_CommandLine_Program = retPROCESS
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.UseShellExecute = False
                    prcINFO.RedirectStandardOutput = True
                    prcINFO.RedirectStandardError = True
                    prcINFO.CreateNoWindow = True
                End With 'prcINFO

                retPROCESS.Start()
            End Function 'Start_Procses

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Start_Windows_Program(ur_exec_path As String, ur_exec_param As String)
                Dim retPROCESS As New System.Diagnostics.Process()
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.Verb = "Open"
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
                    prcINFO.UseShellExecute = True
                End With 'prcINFO

                retPROCESS.Start()
            End Sub 'Start_Procses
        End Class 'gDiagnostics

        Public Class gInteraction
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub AppActivate(ur_window_title As String)
                Microsoft.VisualBasic.Interaction.AppActivate(ur_window_title)
            End Sub
        End Class 'gInteraction

        Public Class gEnvironment
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine() As String
                CommandLine = System.Environment.CommandLine
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ExpandEnvironmentVariables(ur_path As String) As String
                ExpandEnvironmentVariables = System.Environment.ExpandEnvironmentVariables(ur_path)
            End Function
        End Class 'gEnvironment

        Public Class gMsgBox
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetResult(ur_message As String, ur_style As MsgBoxStyle, ur_title As String) As MsgBoxResult
                GetResult = MsgBox(ur_message, ur_style, ur_title)
            End Function
        End Class 'gMsgBox

        Public Class gThread
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Sleep(ur_milliseconds As Integer)
                System.Threading.Thread.Sleep(ur_milliseconds)
            End Sub
        End Class 'gThread

        Public Class gWindowsFS
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Copy(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Copy(ur_source_path, ur_dest_path, True)
            End Sub
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub CreateDirectory(ur_folder_path As String)
                System.IO.Directory.CreateDirectory(ur_folder_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Delete(ur_path As String)
                System.IO.File.Delete(ur_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = System.IO.Directory.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetDirectories(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetDirectories = System.IO.Directory.GetDirectories(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFullPath(ur_partial_path As String) As String
                GetFullPath = System.IO.Path.GetFullPath(ur_partial_path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasDir(ur_search_folder As String) As Boolean
                HasDir = System.IO.Directory.Exists(ur_search_folder)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasFile(ur_search_Path As String) As Boolean
                HasFile = System.IO.File.Exists(ur_search_Path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Move(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Move(ur_source_path, ur_dest_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadAllText(ur_file_path As String) As String
                ReadAllText = System.IO.File.ReadAllText(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadStream(ur_file_path As String) As System.IO.StreamReader
                ReadStream = New System.IO.StreamReader(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub WriteAllText(ur_file_path As String, ur_text As String)
                Call System.IO.File.WriteAllText(ur_file_path, ur_text, Mx.gUTF8_FileEncoding())
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function WriteStream(ur_file_path As String) As System.IO.StreamWriter
                WriteStream = New System.IO.StreamWriter(ur_file_path, False, Mx.gUTF8_FileEncoding())
            End Function
        End Class 'gWindowsFS
    End Class 'glbl

    Public Class TablePKEnum(Of E As {New, bitBASE}, P As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of P, T)
        Private PK As E

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_flag_populate_keys As Boolean = True)
            Me.ttb = New System.Collections.Generic.Dictionary(Of P, T)
            Me.PK = TRow(Of E).glbl.RefKeys.tr_b1(1)
            If ur_flag_populate_keys Then
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    Dim new_row = New T
                    new_row.v(Me.PK) = enmENTRY.name
                    Me.ttb.Add(enmENTRY, new_row)
                Next enmENTRY
            End If 'ur_empty_table
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ur_key As P) As Boolean
            ExistsKey = Me.ttb.ContainsKey(ur_key)
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim enmENTRY = prv.Get_PKStr(Me, ur_row)
            If enmENTRY Is Nothing Then
                Throw New System.Exception("Primary Key must exist in the enumeration: " & ur_row.v(Me.PK))

            ElseIf Me.ttb.ContainsKey(enmENTRY) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_row.v(Me.PK))

            Else
                Me.ttb.Add(enmENTRY, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            InsKey = ret
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKEnum(Of E, P, T)
            Dim ttbRET = New TablePKEnum(Of E, P, T)
            PersistRead = ttbRET
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Me.Ins(CType(row, T))
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T()
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ur_key As P) As T
            SelKey = Me.ttb.Item(ur_key)
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                ret = Me.ttb.Item(ur_key)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            UseKey = ret
        End Function 'UseKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        Private Class prv
            Public Shared Sub Assign_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T, ur_key As P)
                ur_row.v(ur_table.PK) = ur_key.name
            End Sub 'Assign_PKStr

            Public Shared Function Get_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T) As P
                Dim ret As P = Nothing
                Dim strPK = ur_row.v(ur_table.PK)
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    If AreEqual(enmENTRY.name, strPK) Then
                        ret = enmENTRY
                        Exit For
                    End If
                Next enmENTRY

                Get_PKStr = ret
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKEnum

    Public Class TablePKStr(Of E As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of String, T)
        Private PK As Objlist(Of E)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_pk_count As Integer)
            Me.ttb = New System.Collections.Generic.Dictionary(Of String, T)
            Me.PK = New Objlist(Of E)
            With 1 : Dim lstKEYS = TRow(Of E).glbl.RefKeys
                Dim intPK_COUNT = ur_pk_count
                If intPK_COUNT > lstKEYS.Count Then
                    intPK_COUNT = lstKEYS.Count
                End If

                For KEYCTR = 1 To ur_pk_count
                    Me.PK.Add(lstKEYS.Item(b0(KEYCTR)))
                Next
            End With 'lstKEYS
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ParamArray ur_key() As String) As Boolean
            ExistsKey = False
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("ExistsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                ExistsKey = Me.ttb.ContainsKey(strPK_KEY_COMBINED)
            End If 'ur_key
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function DelAll() As TablePKStr(Of E, T)
            DelAll = Me
            Call Me.ttb.Clear()
        End Function 'DelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_row)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

            Else
                Me.ttb.Add(strPK_KEY_COMBINED, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("InsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

                Else
                    ret = New T
                    Call prv.Assign_PKStr(Me, ret, ur_key)
                    Me.ttb.Add(strPK_KEY_COMBINED, ret)
                End If 'Me
            End If 'ur_key

            InsKey = ret
        End Function 'InsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKStr(Of E, T)
            PersistRead = Me
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Dim new_row = New T
                For Each enmENTRY In new_row.RefColKeys
                    new_row.v(enmENTRY) = row.v(enmENTRY)
                Next

                Me.Ins(new_row)
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("SelKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    ret = Me.ttb.Item(strPK_KEY_COMBINED)

                Else
                    ret = New T
                End If 'Me
            End If 'ur_key

            SelKey = ret
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelOnKey(ParamArray ur_key() As String) As TablePKStr(Of E, T)
            Dim ret = Me
            For KEYCTR = 1 To Me.PK.Count
                ret = ret.Sel(Me.PK.Item(b0(KEYCTR)), ur_key(b0(KEYCTR)))
            Next

            SelOnKey = ret
        End Function 'SelOnKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                ret = Me.ttb.Item(strPK_KEY_COMBINED)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(strPK_KEY_COMBINED, ret)
            End If

            UseKey = ret
        End Function 'UseKey

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Assign_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T, ur_key() As String)
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                For KEYCTR = 1 To intPK_KEYS
                    ur_row.v(ur_table.PK.Item(b0(KEYCTR))) = ur_key(b0(KEYCTR))
                Next
            End Sub 'Assign_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_key() As String) As String
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To intPK_KEYS
                    If KEYCTR = 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_key(b0(KEYCTR)).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T) As String
                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To ur_table.PK.Count
                    If KEYCTR > 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_row.v_b1(KEYCTR).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKStr


    Partial Public Class Have
        Partial Private Class prv_sample
            Private Class Have
                Private Shared tblUserBowl As sUserBowl

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Sub Connect()
                    If Have.tblUserBowl Is Nothing Then
                        Have.tblUserBowl = New sUserBowl
                    End If 'sdaTCOL_NAME
                End Sub 'Connect

                Public Class enmUB
                    Inherits bitBASE
                    Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                    Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                End Class

                Public Class enmUN
                    Inherits bitBASE
                    Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p1 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p2 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared to_clipboard As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                End Class

                'Public Shared Function UserBowl() As sUserBowl
                '    Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
                '    Call Have.Connect()
                '    UserBowl = Have.tblUserBowl
                '    If bolFIRST_INIT Then
                '        Call Have.tblUserBowl.InsFrom_Application()
                '        Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                '        Call Have.tblUserBowl.Cboard_CmdlineAudit()
                '    End If
                'End Function 'UserBowl

                Public Class rUserBowl
                    Inherits TRow(Of enmUB)

                    <System.Diagnostics.DebuggerHidden()>
                    Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                        vt = Me
                        Me.v(ur_enm) = ur_val
                    End Function

                    'Public Shadows Function Link_Table(ur_child_table As Have.sReport_Detl, ParamArray ur_key_list() As bitRP) As sReport_Detl
                    '    Dim tblRET = New sReport_Detl
                    '    Link_Table = tblRET
                    '    Dim sdpXLAT = New SdPair(Of bitRT)
                    '    Dim stpKEY_BINDINGS = Strapd()
                    '    For Each keyRP In ur_key_list
                    '        stpKEY_BINDINGS.dS(keyRP.name)
                    '        For Each keyRT In ur_child_table.SelFirst.RefColKeys
                    '            If AreEqual(keyRT.name, keyRP.name) Then
                    '                sdpXLAT.d(keyRP.name, keyRT)
                    '            End If
                    '        Next keyRT
                    '    Next keyRP

                    '    If sdpXLAT.Count <> ur_key_list.Length Then
                    '        Throw New System.Exception("Key bindings not found for RT/RP join: " & stpKEY_BINDINGS.ToString)

                    '    Else
                    '        For Each trwJOIN In ur_child_table.SelAll
                    '            Dim bolFOUND = True
                    '            For Each keyRP In ur_key_list
                    '                Dim keyRT = sdpXLAT.l(keyRP.name)
                    '                If AreEqual(trwJOIN.v(keyRT), Me.v(keyRP)) = False Then
                    '                    bolFOUND = False
                    '                    Exit For
                    '                End If
                    '            Next keyRP

                    '            If bolFOUND Then
                    '                tblRET.Ins(trwJOIN)
                    '            End If
                    '        Next trwJOIN
                    '    End If 'sdpXLAT
                    'End Function 'Link_Table
                End Class 'rUserBowl

                Public Class sUserBowl
                    Inherits TablePKEnum(Of enmUB, enmUN, rUserBowl)

                    'Public Sub Cboard_CmdlineAudit()
                    '    If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    '        Dim strAUDIT = Me.ToString(True)
                    '        Dim ins_msg = Mx.Have.MessageBox.Ins(
                    '            New Mx.Have.rMessageBox().
                    '                vt(enmMB.title, Me.SelKey(enmUN.app_name).v(enmUB.contents)).
                    '                vt(enmMB.text, strAUDIT),
                    '            MsgBoxStyle.OkCancel
                    '            )
                    '        If ins_msg.vUserResponse = MsgBoxResult.Ok Then
                    '            Mx.Have.Clipboard.Ins(
                    '                New Mx.Have.rClipboard().
                    '                vt(enmCB.text, strAUDIT)
                    '                )
                    '        End If
                    '    End If
                    'End Sub 'Cboard_CmdlineAudit

                    'Public Function InsFrom_Application() As rUserBowl
                    '    Dim ret = New rUserBowl
                    '    InsFrom_Application = ret
                    '    'Me.InsKey(enmUN.app_name, New MxText.FileName().d(Mx.Class1.SourcePath).FileGroup)
                    '    'Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                    '    'Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                    '    Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                    '    Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                    '    Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                    '    For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    '        Me.Ins(
                    '            New Have.rUserBowl().
                    '            vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                    '            vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                    '            )
                    '    Next
                    'End Function 'InsFrom_Application

                    'Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    '    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                    'End Function
                End Class 'sUserBowl
            End Class 'Have
        End Class 'prv_sample
    End Class 'Have.prv_sample
End Namespace 'Mx

VBNetProject\VBNetScript

<<ext "VBNetScript.EXE">>

<<ext "VBNetScript.SLN">>

VBNS Project

<<glbl_article_list>>

VBNS Project\~MockTestReport

```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
dbUserInputMock.vb
ScriptRun.vb
subs.vb
RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx2

Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock

    Public Class Want
        Public Shared Function CompileCode_Report_errhnd(ur_commandline_text As String) As Mx.Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Mx.Strapd()
            CompileCode_Report_errhnd = stpRET
            stpRET.d("RED").dLine()
            Dim objERR_LIST = New Mx.ErrListBase : Try
                Call Assistant.CompileCode_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'CompileCode_Report_errhnd
    End Class 'Want

    Public Class Assistant
        Public Shared Sub CompileCode_Report(ur_ret As Mx.Strap)
            Dim windowsfs_env = Have.WindowsFS
            Dim userbowl_cart = Have.UserBowl
            Dim appfolder_bowlname = enmUN.app_folder
            Dim mocktest_cart = Have.MockTest
            Dim intRECS_INSERTED = mocktest_cart.Apply(userbowl_cart, appfolder_bowlname, windowsfs_env)
            Dim intRECS_TESTED = mocktest_cart.Apply(windowsfs_env)

            Dim from_messagebox_bowlname = userbowl_cart.Apply(mocktest_cart, ur_ret)
        End Sub 'CompileCode_Report
    End Class 'Assistant

    Partial Public Class Have
        Partial Public Class sMockTest
            Public Function Apply(ur_userbowl_cart As Have.sUserBowl, ur_appfolder_bowlname As enmUN, ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_ADDED = 0
                Dim strSEARCH_TEST_NAME = "MockTest\*.mock_commandline.txt"
                Dim strSEARCH_RESULT_NAME = ".mock_expect.txt"
                Dim flnAPP_FOLDER = Mx.FileNamed.d(ur_userbowl_cart.SelKey(ur_appfolder_bowlname).Contents)
				Dim fltSEARCH_MOCK_COMMANDLINE = flnAPP_FOLDER.gCopy.d(strSEARCH_TEST_NAME)
                For Each strPATH In ur_windowsfs_env.GetFiles(fltSEARCH_MOCK_COMMANDLINE.gParentDir, fltSEARCH_MOCK_COMMANDLINE.Name, System.IO.SearchOption.TopDirectoryOnly)
					
                    Dim flnTEST_FILE_PATH = Mx.FileNamed.d(strPATH)
                    Dim rowMOCK_TEST = Me.InsKey(strPATH)
                    retREC_ADDED += 1
                    Dim flnTEST_CODE_PATH = flnTEST_FILE_PATH.gParentDir.d(Mx.FileNamed().d(flnTEST_FILE_PATH.FileGroup).FileGroup)
                    For Each strTEST_CODE_PATH In ur_windowsfs_env.GetFiles(flnTEST_CODE_PATH.gParentDir, flnTEST_CODE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.test_code_file, strTEST_CODE_PATH)
                        Exit For
                    Next
					
                    Dim flnRESULT_FILE_PATH = flnTEST_CODE_PATH.gCopy.dAppendEXT(strSEARCH_RESULT_NAME)
                    For Each strEXPECTED_RESULT_PATH In ur_windowsfs_env.GetFiles(flnRESULT_FILE_PATH.gParentDir, flnRESULT_FILE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.mock_expect_file, strEXPECTED_RESULT_PATH)
                        Exit For
                    Next
                Next strPATH

                Apply = retREC_ADDED
            End Function 'Apply ur_userbowl_cart

            Public Function Apply(ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_TESTED = 0
                For Each rowMOCK_TEST In Me.SelAll
                    retREC_TESTED += 1
                    If Mx.HasText(rowMOCK_TEST.v(enmMT.test_code_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Test Code File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    ElseIf Mx.HasText(rowMOCK_TEST.v(enmMT.mock_expect_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Mock Expect File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    Else
						Dim strTEST_CODEFILE_PATH = rowMOCK_TEST.v(enmMT.test_code_file)
                        Dim strCOMMANDLINE_PARMS = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_commandline_file))
                        Dim strEXPECTED_RESULT = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_expect_file))

                        Dim mockTextBox = New Mock.TextBox
                        Dim mockForm = New Mock.Form
                        Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
                        Dim stpTEST_COMMANDLINE = Mx.Strapd().d("vbnetscript.exe").dS("/path=").dSprtr(Mx.qs, strTEST_CODEFILE_PATH).d(Mx.qs).dS(strCOMMANDLINE_PARMS)
                        Call Mx.Want.Compile_And_Run_Script_errhnd(mockUserInput, stpTEST_COMMANDLINE)
                        Dim strFOUND_RESULT = mockTextBox.Text
                        If strFOUND_RESULT = strEXPECTED_RESULT Then
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "1")
						
                        Else
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
                            rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`"))
                        End If 'strFOUND_RESULT
                    End If
                Next rowMOCK_TEST

                Apply = retREC_TESTED
            End Function 'Apply ur_windowsfs_env
        End Class 'sMockTest

        Partial Public Class sUserBowl
            Public Function Apply(ur_mocktest_cart As Have.sMockTest, ur_ret As Mx.Strap) As enmUN
                Dim retUN = enmUN.from_messagebox
                Apply = retUN

                Dim intTEST_PASS = 0
                Dim intTEST_FAIL = 0
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "1" Then
                        intTEST_PASS += 1

                    Else
                        intTEST_FAIL += 1
                    End If
                Next rowMOCK_TEST

                If intTEST_PASS = ur_mocktest_cart.SelAll.Count Then
                    ur_ret.Clear().dLine("GREEN").dLine()
                End If

                ur_ret.dLine(intTEST_PASS.ToString).dS("Tests passed")
                ur_ret.dLine(intTEST_FAIL.ToString).dS("Tests failed")
				ur_ret.dLine()
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "0" Then
                        ur_ret.dLine(rowMOCK_TEST.v(enmMT.test_result_text))
						ur_ret.dLine()
                    End If
                Next rowMOCK_TEST
            End Function 'Apply ur_messagebox_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblMockTest As sMockTest
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblMockTest = New sMockTest
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmMT
        Inherits Mx.bitBASE
        Public Shared mock_commandline_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared mock_expect_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_code_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_result_text As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_pass_count As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
    End Class 'enmMT

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function MockTest() As sMockTest
            Call Have.Connect()
            MockTest = Have.tblMockTest
        End Function

        Public Class rMockTest
            Inherits Mx.TRow(Of enmMT)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmMT, ur_val As String) As rMockTest
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rMockTest

        Public Class sMockTest
            Inherits Mx.TablePKStr(Of enmMT, rMockTest)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                MyBase.New(1)
            End Sub
        End Class
    End Class 'enmMT

    Public Class enmUB
        Inherits Mx.bitBASE
        Public Shared bowl_name As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits Mx.bitBASE
        Public Shared app_folder As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits Mx.bitBASE
        Public Shared Ok As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits Mx.TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = Mx.AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If Mx.HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = Mx.MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = Mx.qs & Have.CmdLineText.Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                Me.SelKey(enmUN.cmdline_table).Contents = Mx.qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx2

VBNS Project\~VersionUpd

```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.FileUpdate_Report_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.FileUpdate_Report_errhnd
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub FileUpdate_Report(ur_ret As Strap)
            Dim userbowl_cart = Have.UserBowl
            Dim appname_bowlname = enmUN.app_name
            Dim appfolder_bowlname = enmUN.app_folder
            Dim windows_msgbox_env = Have.WindowsMsgBox
            Dim windows_fs_env = Have.WindowsFS
            Dim tempfile_cart = Have.TempFile
            tempfile_cart.Apply(userbowl_cart.SelKey(appfolder_bowlname), windows_fs_env)
            Dim report_output_bowlname = userbowl_cart.Apply(tempfile_cart)
            Dim from_messagebox_bowlname = userbowl_cart.Apply(
                ur_userbowl_text:=userbowl_cart.SelKey(report_output_bowlname),
                ur_userbowl_appname:=userbowl_cart.SelKey(appname_bowlname),
                ur_messagebox_env:=windows_msgbox_env
                )
        End Sub 'FileUpdate_Report

        Public Shared Function FileUpdate_Report_errhnd() As Strap
            Dim stpRET = Strapd()
            FileUpdate_Report_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call FileUpdate_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'FileUpdate_Report_errhnd
    End Class 'Want

    Partial Public Class Have
        Partial Class sTempFile
            Public Sub Apply(ur_app_folder As Have.rUserBowl, ur_windows_fs_env As Have.glblWindowsFS)
                Dim flnROOT_FOLDER = FileNamed().d(ur_app_folder.v(enmUB.contents))
                Dim flnMY_PROJECT = flnROOT_FOLDER.gCopy.d("My Project")
                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnROOT_FOLDER, "*.vbproj", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.VBProj, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.VBProj).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.VBProj.name).dS("file in folder"))
                End If

                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnMY_PROJECT, "AssemblyInfo.vb", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.AssemblyInfo, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.AssemblyInfo).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.AssemblyInfo.name).dS("file in folder"))
                End If
            End Sub 'Apply(ur_app_folder
        End Class 'sTempFile

        Partial Public Class sUserBowl
            Public Function Apply(ur_userbowl_text As Have.rUserBowl, ur_userbowl_appname As Have.rUserBowl, ur_messagebox_env As Have.glblWindowsMsgBox) As bitBASE
                Dim retUN = enmUN.from_messagebox
                Apply = retUN
                Dim enrUSER_INPUT = ur_messagebox_env.GetResult(
                    ur_message:=ur_userbowl_text.v(enmUB.contents),
                    ur_title:=ur_userbowl_appname.v(enmUB.contents),
                    ur_style:=MsgBoxStyle.OkOnly
                    )

                If enrUSER_INPUT = MsgBoxResult.Ok Then
                    Me.InsKey(retUN, enmUR.Ok)
                End If
            End Function 'Apply ur_messagebox_cart

            Public Function Apply(ur_tempfile_cart As Have.sTempFile) As enmUN
                Dim retUN = enmUN.report_output
                Apply = retUN
                Dim strDATE = Today.ToString("yyyy.MM.dd")
                Dim intCURRENT = 1

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.VBProj.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<ApplicationRevision>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationRevision>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, InStr(strPARSE, "<") - 1)
                                    If System.Int32.TryParse(strPARSE, intCURRENT) Then
                                        intCURRENT += 1
                                    End If

                                ElseIf StartingWithText(strLINE.TrimStart, "<ApplicationVersion>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationVersion>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, 10)
                                    If AreEqual(strPARSE, strDATE) = False Then
                                        intCURRENT = 1
                                    End If 'strPARSE

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationRevision>")
                                    stmSECOND.Write(intCURRENT)
                                    stmSECOND.WriteLine("</ApplicationRevision>")

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationVersion>")
                                    stmSECOND.Write(Strapd().d(strDATE).d(intCURRENT.ToString("00")).d(".%2a"))
                                    stmSECOND.WriteLine("</ApplicationVersion>")

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.AssemblyInfo.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyVersion(") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyVersion").d("(").d(qs).d(Today.ToString("yyyy.MM.dd")).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                ElseIf StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyFileVersion") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyFileVersion").d("(").d(qs).d(strDATE).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                Me.InsKey(retUN, Strapd().d("Files updated:").dS(ur_tempfile_cart.SelAll.Count.ToString))
            End Function 'Apply ur_tempfield_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblTempFile As sTempFile
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblTempFile = New sTempFile
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmTF
        Inherits bitBASE
        Public Shared file_search As enmTF = TRow(Of enmTF).glbl.NewBitBase()
        Public Shared filename As enmTF = TRow(Of enmTF).glbl.NewBitBase()
    End Class

    Public Class enmTN
        Inherits bitBASE
        Public Shared AssemblyInfo As enmTN = TRow(Of enmTN).glbl.NewBitBase()
        Public Shared VBProj As enmTN = TRow(Of enmTN).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function TempFile() As sTempFile
            Call Have.Connect()
            TempFile = Have.tblTempFile
        End Function

        Public Class rTempFile
            Inherits TRow(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmTF, ur_val As String) As rTempFile
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rTempFile

        Public Class sTempFile
            Private ttb As Objlist(Of rTempFile)
            Private PK As Objlist(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rTempFile)
                Me.PK = New Objlist(Of enmTF)
                Me.PK.Add(enmTF.file_search)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Del(ur_col As enmTF, ur_val As String)
                For ROWCTR = Me.ttb.Count To 1 Step -1
                    If AreEqual(Me.ttb.tr_b1(ROWCTR).v(ur_col), ur_val) Then
                        Me.ttb.RemoveAt(b0(ROWCTR))
                    End If
                Next ROWCTR
            End Sub 'Del

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Ins(ur_from As rTempFile)
                Dim ttbSEL = Me
                Dim stpPK_LIST = Strapd()
                For Each keyPK In Me.PK
                    Dim strCUR_KEY = ur_from.v(keyPK)
                    If stpPK_LIST.Length > 0 Then stpPK_LIST.d(", ")
                    stpPK_LIST.d(strCUR_KEY)
                    If HasText(strCUR_KEY) = False Then
                        Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("PK value must have data:").dS(keyPK.name))
                    Else
                        ttbSEL = ttbSEL.Sel(keyPK, ur_from.v(keyPK))
                    End If
                Next keyPK

                If ttbSEL.SelAll.Count > 0 Then
                    Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("must have unique PK values:").dS(stpPK_LIST.ToString))
                Else
                    Me.ttb.Add(ur_from)
                End If
            End Sub 'Ins

            <System.Diagnostics.DebuggerHidden()>
            Public Sub InsKey(ur_key As enmTN, ur_val As String)
                Dim ret = Me.SelKey(ur_key)
                If HasText(ret.v(enmTF.filename)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmTF.filename, ur_val)
                End If
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmTF, ur_value As String) As sTempFile
                Dim retUB = New sTempFile
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rTempFile)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmTN) As rTempFile
                Dim ret As rTempFile = Nothing
                Dim strKEY = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmTF.file_search), strKEY) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rTempFile
                    Me.ttb.Add(
                        ret.
                        vt(enmTF.file_search, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sTempFile
    End Class 'TF

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Private ttb As Objlist(Of rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rUserBowl)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rUserBowl) As rUserBowl
                Ins = ur_from
                Me.ttb.Add(ur_from)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As String) As rUserBowl
                Dim ret = Me.SelKey(ur_key)
                InsKey = ret
                If HasText(ret.v(enmUB.contents)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmUB.contents, ur_val)
                End If
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As enmUR) As rUserBowl
                InsKey = Me.InsKey(ur_key, ur_val.name)
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.InsKey(enmUN.app_name, FileNamed().d(Mx.Class1.SourcePath).FileGroup)
                Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmUB, ur_value As String) As sUserBowl
                Dim retUB = New sUserBowl
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rUserBowl)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmUN) As rUserBowl
                Dim ret As rUserBowl = Nothing
                Dim strUN = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmUB.bowl_name), strUN) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rUserBowl
                    Me.ttb.Add(
                        ret.
                        vt(enmUB.bowl_name, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

VBNS Project\Roman to Decimal

<<ext "Roman to Decimal ZIP">>

* Asks for a Roman Numeral
* Returns a decimal number or an error with the invalid sequence and the broken rule

```
Namespace Mx
	Public Class mb
		Public Shared FirstExec As Object
		Public Shared uinput As Microsoft.VisualBasic.MsgBoxResult

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub ask(ur_text As String)
			Call prv.Connect()
			If mb.uinput <> MsgBoxResult.Cancel Then
				mb.uinput = Microsoft.VisualBasic.MsgBox(ur_text, MsgBoxStyle.OkCancel, "")
			End If
		End Sub 'ask

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Function GetText(ur_question As String) As String
			GetText = Microsoft.VisualBasic.InputBox(ur_question, "")
		End Function

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub reset()
			Call prv.Connect()
			mb.uinput = MsgBoxResult.Ok
		End Sub

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Sub Connect()
				If mb.FirstExec Is Nothing Then
					mb.uinput = MsgBoxResult.Ok
					mb.FirstExec = "done"
				End If
			End Sub 'Connect
		End Class 'prv
	End Class 'mb

	Public Class UserAction
		Public Shared Function Roman_Numeral_Conversion_Report() As String
			mb.reset()
			Dim strRET_MSG = ""
			Dim strNUMERAL = mb.GetText("Enter a Roman numeral")
			Dim strDECIMAL = Assistant.Roman_Numeral_Conversion_Result(strNUMERAL)
			strRET_MSG = strNUMERAL & " rom. = " & strDECIMAL & " dec."
			Roman_Numeral_Conversion_Report = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Report
	End Class 'UserAction

	Public Class Assistant
		Public Shared Function Roman_Numeral_Conversion_Result(ur_numeral As String) As String
			Dim strRET_MSG = ""
			Dim rmnNUMERAL = New Mx.glblRomanNumeral(ur_numeral)
			strRET_MSG = rmnNUMERAL.Validation_Message
			If strRET_MSG = "" Then
				strRET_MSG = rmnNUMERAL.ToInteger.ToString
			End If

			Roman_Numeral_Conversion_Result = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Result
	End Class 'Assistant

	Public Class glblRomanNumeral
		Private strpNumeral As String

		Private Enum enmLH
			low_or_high_number
			high_number
			low_number
		End Enum

		Private siaSymbol_Size As Mx.sia

		<System.Diagnostics.DebuggerHidden()>
		Public Sub New(ur_numeral As String)
			Me.strpNumeral = ur_numeral.Trim.ToUpper
			Me.siaSymbol_Size = prv.glbl_Symbol_Sizes()
		End Sub

		Public ReadOnly Property Numeral As String
			<System.Diagnostics.DebuggerHidden()>
			Get
				Numeral = Me.strpNumeral
			End Get
		End Property 'Numeral

		Public Function IsValid() As Boolean
			IsValid = (Me.Validation_Message = "")
		End Function

		Public Function Validation_Message() As String
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_Valid

			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, "", symbol_size_table)

			Validation_Message = clrRET_STATE.strNOTICE_MSG
		End Function 'Validation_Message

		Public Function ToInteger() As Integer
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_State
			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				Dim clPREV_STATE = clrRET_STATE
				clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, "", symbol_size_table)

			ToInteger = clrRET_STATE.intRET_NUM
		End Function 'ToInteger

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function glbl_Symbol_Sizes() As Mx.sia
				Dim retSIA = New Mx.sia
				glbl_Symbol_Sizes = retSIA
				retSIA.Add("I", 1)
				retSIA.Add("V", 5)
				retSIA.Add("X", 10)
				retSIA.Add("L", 50)
				retSIA.Add("C", 100)
				retSIA.Add("D", 500)
				retSIA.Add("M", 1000)

				glbl_Symbol_Sizes = retSIA
			End Function 'glbl_Symbol_Sizes

			Public Class Loop_State
				Public enrSTATE As enmLH
				Public strLOW_OR_HIGH_TEMP As String
				Public intRET_NUM As Integer

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Me.enrSTATE = enmLH.high_number
					Me.strLOW_OR_HIGH_TEMP = ""
					Me.intRET_NUM = 0
				End Sub 'New
			End Class 'Loop_State

			Public Class Loop_Valid
				Public strVAL_FOUR As String
				Public strVAL_THREE As String
				Public strVAL_TWO As String
				Public strVAL_ONE As String
				Public intVAL_FOUR As Integer
				Public intVAL_THREE As Integer
				Public intVAL_TWO As Integer
				Public intVAL_ONE As Integer
				Public strNOTICE_MSG As String

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Call prvLoop_Valid.Reset_Symobls(Me)
					Me.strNOTICE_MSG = ""
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia)
					Me.strVAL_FOUR = ur_state.strVAL_THREE
					Me.intVAL_FOUR = ur_state.intVAL_THREE
					Me.strVAL_THREE = ur_state.strVAL_TWO
					Me.intVAL_THREE = ur_state.intVAL_TWO
					Me.strVAL_TWO = ur_state.strVAL_ONE
					Me.intVAL_TWO = ur_state.intVAL_ONE
					Me.strVAL_ONE = ur_new_symbol
					Me.intVAL_ONE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
					Me.strNOTICE_MSG = ur_state.strNOTICE_MSG
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub Assign_NoticeMsg(ur_message As String)
					If strNOTICE_MSG <> "" Then
						strNOTICE_MSG &= vbCrLf & vbCrLf
					End If

					strNOTICE_MSG &= ur_message
					Call prvLoop_Valid.Reset_Symobls(Me)
				End Sub 'Assign_NoticeMsg

				Private Class prvLoop_Valid
					Public Shared Sub Reset_Symobls(ur_state As prv.Loop_Valid)
						ur_state.strVAL_FOUR = ""
						ur_state.intVAL_FOUR = 0
						ur_state.strVAL_THREE = ""
						ur_state.intVAL_THREE = 0
						ur_state.strVAL_TWO = ""
						ur_state.intVAL_TWO = 0
						ur_state.strVAL_ONE = ""
						ur_state.intVAL_ONE = 0
					End Sub 'Reset_Symobls
				End Class 'prv
			End Class 'Loop_Valid

			Public Shared Function Loop_Return_Valid(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_Valid
				Dim retSTATE = New prv.Loop_Valid(ur_state, ur_new_symbol, ur_symbol_size)
				Loop_Return_Valid = retSTATE
				If retSTATE.strVAL_ONE <> "" Then
					If retSTATE.intVAL_ONE = 0 Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							If strLIST <> "" Then
								strLIST &= ", "
							End If

							strLIST &= strENTRY
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used in Roman numerals.")

					ElseIf retSTATE.strVAL_FOUR = retSTATE.strVAL_THREE AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_TWO AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_ONE Then
						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_FOUR & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & ur_new_symbol & "] is not valid: A single symbol may not be repeated more than three times.")

					ElseIf retSTATE.strVAL_TWO = retSTATE.strVAL_ONE AndAlso
					  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
							If Left(strENTRY_VAL, 1) = "1" Then
								If strLIST <> "" Then
									strLIST &= ", "
								End If

								strLIST &= strENTRY
							End If
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be repeated.")

					ElseIf retSTATE.strVAL_TWO <> "" Then
						If retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
							Dim strLIST = ""
							For Each strENTRY In ur_symbol_size.Keys
								Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
								If Left(strENTRY_VAL, 1) = "1" Then
									If strLIST <> "" Then
										strLIST &= ", "
									End If

									strLIST &= strENTRY
								End If
							Next strENTRY

							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used as the lower symbol followed by a higher symbol.")

						ElseIf retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  retSTATE.intVAL_ONE <> retSTATE.intVAL_TWO * 10 Then
							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: The lower symbol must be ten times less value than the following higher symbol.")

						ElseIf retSTATE.strVAL_THREE <> "" Then
							If retSTATE.intVAL_TWO > retSTATE.intVAL_ONE AndAlso
							  retSTATE.intVAL_ONE >= retSTATE.intVAL_THREE Then
								retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: A lower symbol followed by higher symbol must be followed by lower symbol than the first of the series.")
							End If
						End If 'strVAL_THREE
					End If 'strVAL_TWO
				End If 'strVAL_ONE
			End Function 'Loop_Return_Valid

			Public Shared Function Loop_Return_State(ur_state As prv.Loop_State, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_State
				Dim retSTATE = New prv.Loop_State
				Loop_Return_State = retSTATE

				Dim intNEW_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
				Dim intLOW_OR_HIGH_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_state.strLOW_OR_HIGH_TEMP)
				If ur_state.strLOW_OR_HIGH_TEMP = "" Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM
					retSTATE.enrSTATE = enmLH.low_or_high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol

				ElseIf intNEW_VALUE > intLOW_OR_HIGH_VALUE Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intNEW_VALUE - intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ""

				Else
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.low_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol
				End If
			End Function 'Loop_Return_State

			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function Numeral_To_Int(ur_symbol_size As Mx.sia, ur_numeral As String) As Integer
				Numeral_To_Int = 0
				If ur_symbol_size.ContainsKey(ur_numeral) Then
					Numeral_To_Int = ur_symbol_size.Item(ur_numeral)
				End If
			End Function 'Numeral_To_Int
		End Class 'prv
	End Class 'glblRomanNumeral

	Public Class sia
		Inherits System.Collections.Generic.Dictionary(Of String, Integer)
	End Class
End Namespace 'Mx

VBNS Project\Wiki_Move_HTM

<<ext "Wiki Move HTM">>

```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
End Function '2021m01d03
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Const strLIT_WIKI_MOVE_5_SEC = "Wiki Move 5-Sec"
        Const strvLIT_USER_PROFILE_DOWNLOADS = "%USERPROFILE%\downloads"
        Const strLIT_STAR_DOT_HTM = "WikiMove_*-stamp-*.htm"
        Const strLIT_STAR_DOT_HTML = "WikiMove_*-stamp-*.html"
        Const strLIT_STAR_DOT_CARDTXT = "WikiMove_*-stamp-*.card*.txt"

        Public Shared Sub UITimer_to_Poll_FileDir_And_Move(ur_ret As Strap)
            ur_ret.d("QUIT")
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            Dim strUI_FORM_TITLE = strLIT_WIKI_MOVE_5_SEC
            userbowl_cart.SelKey(uiform_title_bowlname).Contents = strUI_FORM_TITLE
            userbowl_cart.SelKey(enmUN.poll_folder).Contents = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)
            If glbl.gDiagnostics.IsRunningWindow(strUI_FORM_TITLE) Then
                glbl.gInteraction.AppActivate(strUI_FORM_TITLE)

            Else
                Dim objFORM = New Mx.WikiMove_Form()
                objFORM.Text = userbowl_cart.SelKey(enmUN.uiform_title).v(enmUB.contents)
                Call objFORM.Display_FolderList()
                objFORM.tmrFIVE_SEC.Start()
                Dim strNEW_DATA_FOLDER = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)

                'System.Windows.Forms.Application.Run(objFORM) only works from a command line program with no forms open. VBNetScript already has a form open.
                Call objFORM.ShowDialog()
            End If 'gDiagnostics
        End Sub 'UITimer_to_Poll_FileDir_And_Move

        Public Shared Function UITimer_to_Poll_FileDir_And_Move_errhnd(ur_commandline_text As String) As Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Strapd()
            UITimer_to_Poll_FileDir_And_Move_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call UITimer_to_Poll_FileDir_And_Move(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'UITimer_to_Poll_FileDir_And_Move_errhnd

        Public Shared Sub Poll_FileDir_And_Move(ur_ui_form As WikiMove_Form)
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            Dim windows_fs_cart = Have.WindowsFS
            Dim filemove_cart = Have.FileMove
            Call ur_ui_form.Display_FolderList()
            filemove_cart.DelAll()
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTM)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTML)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_CARDTXT)
            filemove_cart.Move_Files()
            Dim report_output_bowlname = userbowl_cart.Apply(filemove_cart)
            Dim strREPORT_OUTPUT = userbowl_cart.SelKey(report_output_bowlname).v(enmUB.contents)
            If HasText(strREPORT_OUTPUT) Then
                ur_ui_form.txtOUTPUT.Text = strREPORT_OUTPUT & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move

        Public Shared Sub Poll_FileDir_And_Move_errhnd(ur_ui_form As WikiMove_Form)
            Dim objERR_LIST = New ErrListBase : Try
                Call Poll_FileDir_And_Move(ur_ui_form:=ur_ui_form)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                ur_ui_form.txtOUTPUT.Text = objERR_LIST.ToString & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move_errhnd

        Public Class CombineTextOutput
            Public gText As Strap
            Public gFolderList As Sdata

            Public Sub New(ur_text As Strap, ur_folder_list As Sdata)
                Me.gText = ur_text
                Me.gFolderList = ur_folder_list
            End Sub
        End Class 'CombineTextOutput
    End Class 'sub_main

    Public Class WikiMove_Form
        Inherits System.Windows.Forms.Form

        Public tmrFIVE_SEC As System.Windows.Forms.Timer
        Public txtOUTPUT As System.Windows.Forms.TextBox
        Public intSHOW_FORM As Integer

        Public Sub New()
            Me.intSHOW_FORM = 1

            Me.Name = "Wiki_Move"
            Me.Size = New System.Drawing.Size(400, 400)
            Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen

            Me.txtOUTPUT = New System.Windows.Forms.TextBox()
            Me.txtOUTPUT.Name = "txtOUTPUT"
            Me.txtOUTPUT.Multiline = True
            Me.txtOUTPUT.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
            Me.txtOUTPUT.Dock = System.Windows.Forms.DockStyle.Fill
            Me.Controls.Add(Me.txtOUTPUT)

            Me.tmrFIVE_SEC = New System.Windows.Forms.Timer()
            Me.tmrFIVE_SEC.Interval = 50
            AddHandler Me.tmrFIVE_SEC.Tick, AddressOf Timer1_Tick
        End Sub 'New

        Sub Display_FolderList()
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            If HasText(Me.txtOUTPUT.Text) = False Then
                Me.txtOUTPUT.Text = Strapd().dLine("Listening:").dS(userbowl_cart.SelKey(pollfolder_bowlname).v(enmUB.contents)).dLine().d(Me.txtOUTPUT.Text)
            End If
        End Sub 'Display_FolderList

        Sub Look_For_Files()
            Call Mx.Want.Poll_FileDir_And_Move_errhnd(Me)
        End Sub

        Sub Show_Saved()
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            If Me.intSHOW_FORM = 1 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Normal
                Call AppActivate(userbowl_cart.SelKey(uiform_title_bowlname).v(enmUB.contents))
                Me.tmrFIVE_SEC.Interval = 800
                Me.intSHOW_FORM = 2

            ElseIf Me.intSHOW_FORM = 2 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Minimized
                Me.intSHOW_FORM = 0

            ElseIf Me.intSHOW_FORM = 0 Then
                If Me.WindowState <> System.Windows.Forms.FormWindowState.Minimized Then
                    Me.intSHOW_FORM = 6
                End If

            Else
                Me.intSHOW_FORM -= 1
            End If
        End Sub 'Show_Saved

        Sub Timer1_Tick(sender As Object, e As System.EventArgs)
            Me.tmrFIVE_SEC.Stop()
            Me.tmrFIVE_SEC.Interval = 5000
            Call Look_For_Files()
            Call Show_Saved()
            Me.tmrFIVE_SEC.Start()
        End Sub 'Timer1_Tick
    End Class 'WikiMove_Form




    Public Class Have
        Partial Class sFileMove
            Public Sub Apply(ur_windows_fs_cart As Have.glblWindowsFS, ur_userbowl_cart As Have.sUserBowl, ur_poll_folder_bowlname As enmUN, ur_filespec As String)
                Dim strPOLL_FOLDER = ur_userbowl_cart.SelKey(ur_poll_folder_bowlname).Contents
                For Each strFILE_PATH In ur_windows_fs_cart.GetFiles(strPOLL_FOLDER, ur_filespec, System.IO.SearchOption.TopDirectoryOnly)
                    Dim flnFILE_NAME = FileNamed().d(strFILE_PATH)
                    Dim sdaEXT_LIST = flnFILE_NAME.ExtList
                    Dim strDEST_PATH_ENCODED_IN_NAME = flnFILE_NAME.Name.Substring("WikiMove_".Length)
                    Dim strDEST_PATH = strDEST_PATH_ENCODED_IN_NAME.Replace("-colon-", ":").Replace("-fslash-", "\")
                    Dim intSTAMP = InStr(strDEST_PATH, "-stamp-")
                    strDEST_PATH = Left(strDEST_PATH, intSTAMP - 1)
                    Dim strEXT = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count))
                    If sdaEXT_LIST.Count > 1 Then
                        Dim strEXT2 = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count - 1))
                        If AreEqual(strEXT, ".txt") AndAlso
                          StartingWithText(strEXT2, ".card") Then
                            strEXT = ".card.txt"
                        End If
                    End If 'sdaEXT_LIST

                    strDEST_PATH &= strEXT
                    Me.Ins(
                        New rFileMove().
                        vt(enmFM.src_file_path, strFILE_PATH).
                        vt(enmFM.dest_file_path, strDEST_PATH)
                        )
                Next strFILE_PATH
            End Sub 'Apply ur_windows_fs_cart

            Public Sub Move_Files()
                Dim lstLEN = New System.Collections.Generic.List(Of Integer)
                For Each rowFILE In Me.SelAll
                    Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                    Dim intLEN = strFILE_PATH.Length
                    If lstLEN.Contains(intLEN) = False Then
                        lstLEN.Add(intLEN)
                    End If
                Next rowFILE

                Call lstLEN.Sort()
                For Each intLEN In lstLEN
                    For Each rowFILE In Me.SelAll
                        Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                        If strFILE_PATH.Length = intLEN Then
                            Dim strDEST_PATH = rowFILE.v(enmFM.dest_file_path)
                            glbl.gWindowsFS.Move(strFILE_PATH, strFILE_PATH & ".TDLY")
                            glbl.gWindowsFS.Delete(strDEST_PATH)
                            glbl.gWindowsFS.Move(strFILE_PATH & ".TDLY", strDEST_PATH)
                        End If 'strFILE_PATH
                    Next rowFILE
                Next intLEN
            End Sub 'Move_Files
        End Class 'sFileMove

        Partial Class sUserBowl
            Public Function Apply(ur_filemove_cart As sFileMove) As enmUN.zreport_output
                Dim retKEY = enmUN.report_output
                Apply = retKEY
                Dim stpREPORT = Strapd()
                For Each rowFILE In ur_filemove_cart.SelAll
                    stpREPORT.dLine(Now.ToString("tt hh:mm:ss")).d(":").dS(rowFILE.v(enmFM.dest_file_path))
                Next rowFILE

                Me.SelKey(retKEY).v(enmUB.contents) = stpREPORT
            End Function 'Apply(ur_filemove_cart
        End Class 'sUserBowl
    End Class 'Have



    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblFileMove As sFileMove
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblFileMove = New sFileMove
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmFM
        Inherits bitBASE
        Public Shared src_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
        Public Shared dest_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
    End Class

    Partial Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function FileMove() As sFileMove
            Call Have.Connect()
            FileMove = Have.tblFileMove
        End Function

        Public Class rFileMove
            Inherits TRow(Of enmFM)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmFM, ur_val As String) As rFileMove
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rFileMove

        Public Class sFileMove
            Private ttb As Objlist(Of rFileMove)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rFileMove)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub DelAll()
                Me.ttb.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rFileMove) As rFileMove
                Ins = ur_from
                Dim ttbSEL = Me
                Me.ttb.Add(ur_from)
            End Function 'Ins

            Public ReadOnly Property SelAll() As Objlist(Of rFileMove)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sFileMove
    End Class 'Have

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared poll_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared uiform_title As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function 'UserBowl

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = Have.WindowsMsgBox.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(strAUDIT)
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

View All Cards

<$list filter="[all[tiddlers]!tag[EXTLINK]!tag[IMG]!tag[INDEX]!tag[MCR]!tag[META]!has[draft.of]!is[image]!is[tag]!is[system]has[tags]!prefix[undefined]sort[title]]">
<hr>
<h2><$link to=<<currentTiddler>> /></h2>
{{||$:/core/ui/ViewTemplate/tags}}
<$transclude mode="block"/>
</$list>

View All Code

<$list variable=cur_card_pk filter="[!has[draft.of]!prefix[undefined]!prefix[$]] [prefix[$]!has[draft.of]has[tags]] +[sort[title]]">
<hr>
<h2><$link to=<<cur_card_pk>> /></h2>
<$list variable=cur_card_tags filter="[<cur_card_pk>tags[]]">
<<cur_card_tags>> 
</$list><!--cur_card_text-->
<$list variable=cur_card_text filter="[<cur_card_pk>get[text]]">
<$codeblock code=<<cur_card_text>> />
</$list><!--cur_card_text-->
</$list><!--cur_card_pk-->

WindowsCLI

<<glbl_article_list>>

WindowsCLI\Batch Replacement Parameters

"""
User Replacement Text = UrProgram

[Example.cmd file]
- SET CUR_DIR=%~dp0
- "%CUR_DIR%UrProgram.exe"

WindowsCLI\Command line hide Errors

"""
[Windows CLI]
- [Turn off standard messages being echoed to the console]
- `@@ECHO OFF`

[https://docs.microsoft.com/en-us/troubleshoot/cpp/redirecting-error-command-prompt]
- To redirect the error message to NUL, use the following command:
"""

```
dir file.xxx 2> nul
```

"""
- You can print the errors and standard output to a single file by using the &1 command to redirect the output for STDERR to STDOUT and then sending the output from STDOUT to a file:
"""

```
dir file.xxx 1> output.msg 2>&1
```

WindowsCLI\Command list

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands

"""

Prerequisites
The information that is contained in this topic applies to:Windows Server 2019

Windows Server (Semi-Annual Channel)

Windows Server 2016

Windows Server 2012 R2

Windows Server 2012

Windows Server 2008 R2

Windows Server 2008

Windows 10

Windows 8.1Command shell overview
The Command shell was the first shell built into Windows to automate routine tasks, like user account management or nightly backups, with batch (.bat) files. With Windows Script Host you could run more sophisticated scripts in the Command shell. For more information, see
cscript
or
wscript
. You can perform operations more efficiently by using scripts than you can by using the user interface. Scripts accept all Commands that are available at the command line.

Windows has two command shells: The Command shell and
PowerShell
. Each shell is a software program that provides direct communication between you and the operating system or application, providing an environment to automate IT operations.

PowerShell was designed to extend the capabilities of the Command shell to run PowerShell commands called cmdlets. Cmdlets are similar to Windows Commands but provide a more extensible scripting language. You can run Windows Commands and PowerShell cmdlets in Powershell, but the Command shell can only run Windows Commands and not PowerShell cmdlets.

For the most robust, up-to-date Windows automation, we recommend using PowerShell instead of Windows Commands or Windows Script Host for Windows automation.

Note

You can also download and install
PowerShell Core
, the open source version of PowerShell. Caution

Incorrectly editing the registry may severely damage your system. Before making the following changes to the registry, you should back up any valued data on the computer. Note

To enable or disable file and directory name completion in the Command shell on a computer or user logon session, run
regedit.exe
and set the following
reg_DWOrd value
:

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\completionChar\reg_DWOrd

To set the
reg_DWOrd
value, use the hexadecimal value of a control character for a particular function (for example,
0 9
is Tab and
0 08
is Backspace). User-specified settings take precedence over computer settings, and command-line options take precedence over registry settings.Command-line reference A-Z
To find information about a specific Windows Command, in the following A-Z menu, click the letter that the Command starts with, and then click the Command name.

A append
arp
assoc
at
atmadm
attrib
auditpol
autochk
autoconv
autofmt
B bcdboot
bcdedit
bdehdcfg
bitsadmin
bitsadmin addfile
bitsadmin addfileset
bitsadmin addfilewithranges
bitsadmin cancel
bitsadmin complete
bitsadmin create
bitsadmin getaclflags
bitsadmin getbytestotal
bitsadmin getbytestransferred
bitsadmin getcompletiontime
bitsadmin getcreationtime
bitsadmin getdescription
bitsadmin getdisplayname
bitsadmin geterror
bitsadmin geterrorcount
bitsadmin getfilestotal
bitsadmin getfilestransferred
bitsadmin getminretrydelay
bitsadmin getmodificationtime
bitsadmin getnoprogresstimeout
bitsadmin getnotifycmdline
bitsadmin getnotifyflags
bitsadmin getnotifyinterface
bitsadmin getowner
bitsadmin get priority
bitsadmin getproxybypasslist
bitsadmin getproxylist
bitsadmin getproxyusage
bitsadmin getreplydata
bitsadmin getreplyfilename
bitsadmin getreplyprogress
bitsadmin getstate
bitsadmin gettype
bitsadmin help
bitsadmin info
bitsadmin list
bitsadmin listfiles
bitsadmin monitor
bitsadmin nowrap
bitsadmin rawreturn
bitsadmin removecredentials
bitsadmin replaceremoteprefix
bitsadmin reset
bitsadmin resume
bitsadmin setaclflag
bitsadmin setcredentials
bitsadmin setdescription
bitsadmin setdisplayname
bitsadmin setminretrydelay
bitsadmin setnoprogresstimeout
bitsadmin setnotifycmdline
bitsadmin setnotifyflags
bitsadmin setpriority
bitsadmin setproxysettings
bitsadmin setreplyfilename
bitsadmin suspend
bitsadmin takeownership
bitsadmin Transfer
bitsadmin util
bitsadmin wrap bootcfg
bootcfg addsw
bootcfg copy
bootcfg dbg1394
bootcfg debug
  bootcfg default
bootcfg delete
bootcfg ems
bootcfg query
bootcfg raw
bootcfg rmsw
bootcfg timeout break
C cacls
call
cd
certreq
certutil
change
change logon
change port
change user chcp
chdir
chglogon
chgport
chgusr
chkdsk
chkntfs
choice
cipher
cleanmgr
clip
cls
Cmd
cmdkey
cmstp
color
comp
compact
convert
copy
cprofile
cscript
D date
dcgpofix
defrag
del
dfsrmig
diantz
dir
diskcomp
diskcopy
diskpart
diskperf
diskraid
diskshadow
dispdiag
dnscmd
doskey
driverquery
E echo
edit
endlocal
erase
eventcreate
eventquery
eventtriggers
evntcmd
exit
expand
extract
F fc
find
findstr
finger
flattemp
fondue
for
forfiles
format
freedisk
fsutil
fsutil 8dot3name
 fsutil behavior
 fsutil file
fsutil fsinfo
fsutil hardlink
fsutil objectid
fsutil quota
fsutil repair
fsutil reparsepoint
fsutil resource
fsutil sparse
fsutil tiering
fsutil transaction
fsutil usn
fsutil volume
fsutil wim ftp
ftype
fveupdate
G getmac
gettype
goto
gpfixup
gpresult
gpupdate
graftabl
H help
helpctr
hostname
I icacls
if
inuse
ipconfig
ipxroute
irftp
J jetpack
K klist
ksetup
ksetup:setrealm
ksetup:mapuser
ksetup:addkdc
ksetup:delkdc
ksetup:addkpasswd
ksetup:delkpasswd
ksetup:server
ksetup:setcomputerpassword
ksetup:removerealm
ksetup:domain
ksetup:changepassword
ksetup:listrealmflags
ksetup:setrealmflags
ksetup:addrealmflags
ksetup:delrealmflags
ksetup:dumpstate
ksetup:addhosttorealmmap
ksetup:delhosttorealmmap
ksetup:setenctypeattr
ksetup:getenctypeattr
ksetup:addenctypeattr
ksetup:delenctypeattr ktmutil
ktpass
L label
lodctr
logman
logman create
logman query
logman start &124; stop
logman delete
logman update
logman import &124; export logoff
lpq
lpr
M macfile
makecab
manage-bde
manage-bde: status
manage-bde: on
manage-bde: off
manage-bde: pause
manage-bde: resume
manage-bde: lock
manage-bde: unlock
manage-bde: autounlock
manage-bde: protectors
manage-bde: tpm
manage-bde: setidentifier
manage-bde: ForceRecovery
manage-bde: changepassword
manage-bde: changepin
manage-bde: changekey
manage-bde: KeyPackage
manage-bde: upgrade
manage-bde: WipeFreeSpace mapadmin
Md
mkdir
mklink
mmc
mode
more
mount
mountvol
move
mqbkup
mqsvc
mqtgsvc
msdt
msg
msiexec
msinfo32
mstsc
N nbtstat
netcfg
netsh
netstat
Net print
nfsadmin
nfsshare
nfsstat
nlbmgr
nslookup
nslookup exit command
nslookup finger command
nslookup help
nslookup ls
nslookup lserver
nslookup root
nslookup server
nslookup set
nslookup set all
nslookup set class
nslookup set d2
nslookup set debug
nslookup set domain
nslookup set port
nslookup set querytype
nslookup set recurse
nslookup set retry
nslookup set root
nslookup set search
nslookup set srchlist
nslookup set timeout
nslookup set type
nslookup set vc
nslookup view ntbackup
ntcmdprompt
ntfrsutl
O openfiles
P pagefileconfig
path
pathping
pause
pbadmin
pentnt
perfmon
ping
pnpunattend
pnputil
popd
PowerShell
PowerShell_ise
print
prncnfg
prndrvr
prnjobs
prnmngr
prnport
prnqctl
prompt
pubprn
pushd
pushprinterconnections
Q qappsrv
qprocess
query
quser
qwinsta
R rcp
rd
rdpsign
recover
reg
reg add
reg compare
reg copy
reg delete
reg export
reg import
reg load
reg query
reg restore
reg save
reg unload regini
regsvr32
relog
rem
ren
rename
repair-bde
replace
reset session
rexec
risetup
rmdir
robocopy
route_ws2008
rpcinfo
rpcping
rsh
rundll32
rwinsta
S schtasks
scwcmd
scwcmd: analyze
scwcmd: configure
scwcmd: register
scwcmd: rollback
 scwcmd: transform
 scwcmd: view
 

secedit
secedit:analyze
secedit:configure
secedit:export
secedit:generaterollback
secedit:import
secedit:validate serverceipoptin
Servermanagercmd
serverweroptin
set
setlocal
setx
sfc
shadow
shift
showmount
shutdown
sort
start
subst
sxstrace
sysocmgr
systeminfo
T takeown
tapicfg
taskkill
tasklist
tcmsetup
telnet
tftp
time
timeout
title
tlntadmn
tpmvscmgr
tracerpt
tracert
tree
tscon
tsdiscon
tsecimp
tskill
tsprof
type
typeperf
tzutil
U unlodctr
V ver
verifier
verify
vol
vssadmin
-W waitfor
wbadmin
wbadmin enable backup
wbadmin disable backup
wbadmin start backup
wbadmin stop job
wbadmin get versions
wbadmin get items
wbadmin start recovery
wbadmin get status
wbadmin get disks
wbadmin start systemstaterecovery
wbadmin start systemstatebackup
wbadmin delete systemstatebackup
wbadmin start sysrecovery
wbadmin restore catalog
wbadmin delete catalog wdsutil
wecutil
wevtutil
where
whoami
winnt
winnt32
winpop
winrs
wmic
wscript
X xcopy

WindowsCLI\Environment Variables

!! Windows CLI Environment Variable examples

<<ext "Windows Environment Variable List">>

* Environment variable %USERPROFILE%

User-replaced value = UrUserName

!! Show the Current Directory environment variable
* [Windows CLI]
* `ECHO %CD%`
* Press enter -> `C:\UrFolderPath\UrSubfolder`

!! Navigate to the C:\Users\UrUserName folder
* [Windows CLI]
* `cd %USERPROFILE%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName`

!! Navigate to the C:\Users\UrUserName\AppData\Local\Temp folder
* `cd %TEMP%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName\AppData\Local\Temp`

!! Navigate to the C:\Users\UrUserName\AppData\Roaming folder
* `cd %APPDATA%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName\AppData\Roaming`

WindowsCLI\Unicode characters

!! Use the standard Windows ANSI Character input
<<ext "Windows Alt-Numpad Unicode">>
* Hold down Alt key, then type the Decimal sequence using only the 0-9 on the Numeric Keypad
* Note: This only works for the 255 characters in the current Windows code page

!! Enable Alt-Numeric Keypad input of Unicode Characters
* Start `RegEdit.exe`
* Navigate to`HKEY_CURRENT_USER\Control Panel\Input Method`
!!
* [New String Value]
* name = `EnableHexNumpad`
* value = `1`
!!
* [Start Menu]
* Reboot your computer
!!
* [In any Windows program]
* Turn on `Numlock`

* Hold down `Alt`-key, then type the Numeric Keypad Plus (+) key once
* Still holding down the `Alt`-key, type the hexadecimal sequence using only the letters A-F on the main keyboard and 0-9 on the Numeric Keypad
* Release the `Alt`-key -> Windows pastes the Unicode character in the current program window
* Note: This may not work for 5-digit hexadecimal codes like U+1F937

!! Use the FileFormat.Info tool Unicode Input

<<ext "FileFormat.Info UnicodeInput">>

[In any program]
* Hold down 'Alt'-key, then type the Numeric Keypad Plus (+) key -> Opens dialog box
* Note: The `U+` displayed in the window means "Enter a Unicode character number in hexadecimal format"
* Type in a hexadecimal number
* Press enter -or- Click button Send -> Closes window, types desired Unicode character in foreground window

<<ext "FileFormat.Info UnicodeInput.ZIP">>

* Note: This EXE program is able to be started from anywhere
* Note: Closing the window minimizes to the system tray as `blue circle with white lowercase letter i`

!! Display Unicode UTF-8 characters in Windows CLI

* [In some UrProgram.cmd file or Command Prompt window]
* First put the line: `@chcp 65001>nul`
* Stream UTF-8 characters from files to the Command Prompt window -> Unicode characters are shown correctly
* Note: If you do not change the code page, Unicode characters will be split into as High- and Low-ASCII characters from the current Windows code page

<<ext "WindowsCLI Unicode Support">>
* HEX input delivers a character on KeyUp of Alt; all the other ways to deliver a character happen on KeyDown; so many applications are not ready to see a character on KeyUp. (Only applicable to applications using Console-I/O API.)
* Conclusion: Many application would not react on HEX input events.
* Note: Unless your keyboard layout supports input of A LOT of characters without prefix keys, some buggy applications may skip characters when you Paste via Console’s UI
!!
* One should also keep in mind that the “alternative, ‘more capable’ consoles” for Windows are not consoles at all. They do not support Console-I/O APIs, so the programs which rely on these APIs to work would not function. (The programs which use only “File-I/O APIs to the console filehandles” would work fine, though.)
* Note: One example of such non-console is a part of MicroSoft’s Powershell. 

!! Change the default Codepage of Windows console
* [RegEdit.exe]
* Navigate to `HKEY_CURRENT_USER\Software\Microsoft\Command Processor`
!!
* [New String Value]
* Name = `Autorun`
* Value = `chcp 65001`
!!
* Actually, the trick is that the command prompt actually understands these non-english characters, just can't display them correctly
* Note: When I enter a path in the command prompt that contains some non-english chracters it is displayed as "?? ?????? ?????"
* Note:  When you submit your command (cd "??? ?????? ?????" in my case), everything is working as expected

!! <<ext "Windows Terminal Unicode Support">>
* Windows Terminal is a new, modern, fast, efficient, powerful, and productive terminal application for users of command-line tools and shells like Command Prompt, PowerShell, and WSL.

YouTube

<<glbl_article_list>>

YouTube\Captions text

!! Export closed captions text file from a YouTube video page
* Note: Android O/S will need to show the YouTube page as a Desktop Site
!!
* [Top-right icons]
* Click the three-dots menu, option Desktop site -> Reloads page
!!
* [Below video, Right-side icons]
* Click the three-dots menu, option Open Transcript -> Navigates page below video or right-side of video
* You can highlight the captions text and copy to the clipboard
* Note: You can paste the captions text into a document and save or print them

!! Find closed captions text file in YouTube video HTML content on Windows
* Type Ctrl-A to Select all text on the page
* Paste all text into a new text document
* At the top of the file, search down for "00:" to find the first line of the captions text
* Delete all text above this line
!!
* At the bottom of the file, search up for "00:" to find the last line of the captions text
* Delete all text below this line
* The remaining lines are the closed captions file

!! Find closed captions text file in YouTube video HTML content on Android O/S
* Search for "views" or [the video title] to find the end of the captions text


template Home Button

$:/positivesigner/home-button $:/tags/ViewTemplate


TiddlyWiki

DOC

  1. Add Tag to All Cards
  2. Backlink to HTML,HTM
  3. Button navigate to Card
  4. Button Set Field
  5. Checkbox edit
  6. Clipboard Copy
  7. Code View or Copy data
  8. Codeblock Widget
  9. Compare Lines
  10. Construct a Calendar
  11. Core Macro Definition
  12. CSS Classes
  13. CSS without classes
  14. Data Tiddler
  15. Date Part
  16. Decimal To Hex
  17. Delete All Cards with Tag
  18. DivPop btn
  19. DivPop glbl
  20. Embed Font
  21. Encrypt file
  22. External Link organization
  23. Filter Operators
  24. Fonts via URL
  25. Global Card Footer
  26. Global Macro
  27. Group Totals
  28. Hard Line Breaks
  29. Hidden on Static File
  30. iFrame
  31. Ignore WikiText formatting
  32. Image
  33. Image link opens Card
  34. Import Macros
  35. Javascript Calculation in Bookmarklet
  36. Keep words together on one line
  37. Keyboard Shortcut
  38. List Links from Numbered Fields
  39. List Links of Prefixed Cards
  40. List Links standard
  41. List Widget
  42. Local Video or Audio Files
  43. Pagination
  44. Popup State Clear All
  45. Published Tools
  46. Recently Changed Cards
  47. Regular Expression
  48. Reveal Section and Copy Data
  49. Save Wiki and Export HTML
  50. Search all Fields
  51. Section Display
  52. Source Code Samples
  53. Split Lines into Storage
  54. Temp Table
  55. Text Differences
  56. Textbox field
  57. TiddlySaver from Downloads
  58. Transclude Card Field
  59. Unicode Character List
  60. Unicode Codepoints Used
  61. Upload File
  62. Video and Audio
  63. View All Cards
  64. Wikify Text
  65. WikiText Formatting
  66. Word Wrap


TiddlyWiki\Add Tag to All Cards

AssignVariable FileSystem TWCard
<$button>
<$action-setfield $tiddler="Test1" tags="COPY"/>
Reset Test1 Card's Tag list with just COPY
</$button>

<$button>
<$list variable=cur_card filter="[is[tiddler]!prefix[$:/state/]]">
<$list variable=has_tag filter="[<cur_card>tags[]count[]!match[0]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[append[COPY]]"/>
</$list>
</$list>
Append COPY tag to all Cards that already have tags
</$button>

<$button>
<$list variable=cur_card filter="[tag[COPY]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[remove[COPY]]"/>
</$list>
Remove COPY tag from all Cards
</$button>

TiddlyWiki\Backlink to HTML,HTM

CodeLibrary FileSystem TWCard

Title = ext TW Return

\define TW_Return(ur_url, ur_link_title)
<div style="float:right"><a href="$ur_url$"> ($ur_link_title$)</a></div>
\end
<$list filter="[<tv-config-toolbar-icons>match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="TiddlyWiki view of website" />
</$list>
</$list>
<$list filter="[<tv-config-toolbar-icons>!match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]split[.htm]join[.html]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="Static HTML view of website" />
</$list>
</$list>

TiddlyWiki\Button navigate to Card

FileSystem TWCard UserAction
<$vars new_code="Test1">
<$list variable=new_pk filter="[<new_code>addprefix[$:/state/popup/]]">
<$button>
<$action-sendmessage $message="tm-new-tiddler" title=<<new_pk>> tags="OneTag [[Another Tag]]" text=<<now "Today is DDth, MMM YYYY">>/>
Create Code ''<<new_code>>'' and Edit
</$button><br>

<$button>
<$action-setfield $tiddler=<<new_pk>> text="yes"/>
<$action-navigate $to=<<new_pk>>/>
Create Code ''<<new_code>>'' and Show
</$button><br>

<$link to=<<new_pk>> /><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
Close Code: ''<<new_code>>''
</$button><br>

<$list filter="[<currentTiddler>!prefix[Draft of]]" variable=strCARD_PK>
<$button>
<$list filter="[list[$:/StoryList]] -[<strCARD_PK>]" variable=strCLOSE_PK>
<$action-sendmessage $message="tm-close-tiddler" $param=<<strCLOSE_PK>>/>
</$list>
Close all other open Codes
</$button>
</$list><br>

<$button>
<$action-sendmessage $message="tm-delete-tiddler" $param=<<new_pk>> />
Delete Card: ''<<new_card>>'' with confirmation
</$button><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
<$action-deletetiddler $tiddler=<<new_pk>> />
Delete Card: ''<<new_card>>'' without confirmation
</$button>
</$list><!--new_pk-->
</$vars><!--new_card-->

TiddlyWiki\Button Set Field

AssignVariable TWCard UserAction
<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="yes"/>
Set UrCardPK = yes
</$button>

<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="no"/>
Set UrCardPK = no
</$button>

TiddlyWiki\Checkbox edit

AssignVariable TWCard UserAction
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler="$:/state/popup/checkUseIt">Use It</$checkbox>

TiddlyWiki\Clipboard Copy

AssignVariable TWCard UserAction

Tags = $:/tags/Macro

\define cboard_copy(ur_text)
<pre>$ur_text$</pre>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end
\define cboard_pwd(ur_text ur_pk)
<$reveal type="nomatch" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="show">Show</$button>

</$reveal>
<$reveal type="match" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="hide">Hide</$button>
<pre>$ur_text$</pre>
</$reveal>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end

TiddlyWiki\Code View or Copy data

CodeLibrary Extract TWCard

Title = mcr glbl_code_split

Tags = $:/tags/Macro

\define glbl_code_block(ur_card_pk)
[[$ur_card_pk$]]
<$codeblock code={{$ur_card_pk$}} />
\end
\define glbl_code_linenum(ur_card_pk, ur_skip_count, ur_section_size, ur_disp_linenum)
<div style="clear:both">[[$ur_card_pk$]]</div>
<$list filter="[[$ur_skip_count$]!match[]else[0]]" variable=intSKIP_COUNT>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>count[]]" variable=intLINE_COUNT>
<$list filter="[[$ur_section_size$]!match[]!match[0]else<intLINE_COUNT>]" variable=intSECTION_SIZE>
<$list filter="[range<intSECTION_SIZE>]" variable=intCUR_LINE>
<$list filter="[<intCUR_LINE>subtract[1]]" variable=IntREMOVE_LINE>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>butfirst<IntREMOVE_LINE>first[]]" variable=strCUR_LINE>
<$list filter="[[$ur_disp_linenum$]!match[n]!match[0]]"><div style="float:left"><<intCUR_LINE>></div></$list>
<$codeblock code=<<strCUR_LINE>> />
</$list></$list></$list></$list></$list></$list>
\end
\define glbl_code_split_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]splitregexp[\u0009]join[__	__]splitregexp[\u0020]join[__ __]splitregexp[\u0022\u0022\u0022]join[&#x0022;&#x0022;&#x0022;]]"><<currentTiddler>>
</$list></$list>
\end
\define glbl_code_split_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_split_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_split_data()
<$macrocall $name=glbl_code_split_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_split_next_group_disp(ur_rem_counter)
<$list filter="[{$ur_rem_counter$}subtract[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_split_disp(ur_source_card_pk, ur_temp_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to find: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
Source data: [[$ur_source_card_pk$]]<br>
\end
\define glbl_code_split_combine()
$(currentTiddler)$$(str_html_out)$
\end
\define glbl_code_split_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]add[1]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_card_pk>> text="" />
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_split(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_split_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_split_disp ur_source_card_pk=<<source_card_pk>> ur_temp_card_pk=<<temp_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$wikify name=str_html_out text=<<glbl_code_split_data>> >
        <$list filter="[<temp_card_pk>get[text]else[]]"><$vars combine_html_out=<<glbl_code_split_combine>> >
        <$action-setfield $tiddler=<<temp_card_pk>> text=<<combine_html_out>> />
         </$vars></$list>
        <$macrocall $name=glbl_code_split_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> />
        </$wikify>
      
      Find next 100 lines
      </$button><br>

    <$edit-text tiddler=<<temp_card_pk>> autoHeight=no />
    </$vars>
  </$list>
\end
\define glbl_code_disp_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u00A0]join[&nbsp;]splitregexp[\u0009]join[&nbsp;&nbsp;&nbsp;&nbsp;]splitregexp[\u0020]join[&nbsp;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]]"><<currentTiddler>><br></$list></$list>
\end
\define glbl_code_disp_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_disp_data()
<$macrocall $name=glbl_code_disp_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_disp_next_group_disp(ur_rem_counter, ur_oper)
<$list filter="[{$ur_rem_counter$}$ur_oper$[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_disp_disp(ur_source_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to browse: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
\end
\define glbl_code_disp_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_disp(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_disp_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
[[$ur_card_pk$]]<br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_disp_disp ur_source_card_pk=<<source_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="subtract" />
      
      Browse next 100 lines
      </$button><br>
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="add" />
      
      Browse prev 100 lines
      </$button><br>

    <<glbl_code_disp_data>>
    </$vars>
  </$list>
\end

<!--<$macrocall $name=glbl_code_disp ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_disp "WebNotes\Data 1 >>-->

<!--Does not pass through the \u0009 tab or \u00A0 non-breaking space characters. Chrome highlight and copy puts spaces on the clipboard.-->

<!--[[WebNotes\Data]]-->

<!--<$macrocall $name=glbl_code_split ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_block "UrCardPK">>-->

<!--<<glbl_code_linenum "UrCardPK" 0 15 n>>-->

TiddlyWiki\Codeblock Widget

CodeLibrary Formatting Text TWCard
```
sample code "here" and "there"
```

You can use the <$codeblock> widget to display text as the three-backticks TiddlyWiki formatting block. Make sure to put an enter at the end of the string if it ends with d-quotes.

<$codeblock code="""sample code "here" and "there"
"""/>

If you need to show text triple d-quotes in a code string, define a macro to return the string literal instead of passing in a code string.

\define sample_data_e3() sample code "here" and "there"

Make sure to put a leading space or some trailing comment text on any line within the macro that has \end by itself. Otherwise the macro definition will end early.

\define sample_data_e4()
sample
code """here"""
and "there"
\end <--Last line of macro

Another way to display a Card's content is by using the triple-curly-brace inclusion.

<$codeblock code={{{ [[UrCardPK]get[text]] }}}/>

TiddlyWiki\Compare Lines

Extract Formatting Text TWCard
<$diff-text source={{t1}} dest={{mcr glbl_section_disp}}/>

Name = mcr glbl_compare_lines

Tag = $:/tags/Macro

\define glbl_compare_lines_results_table(ur_card_pk, ur_second_pk, ur_row_count)
<table><tr>
<th>''Line''</th>
<th>Show text</th>
<th>First Side<br>Second Side</th>
</tr>
<$list filter="[range<intSECOND_COUNT>subtract[1]]" variable="intCUR_ENTRY">
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]]" variable="strFIRST_LINE">
<$list filter="[{$ur_second_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]!match<strFIRST_LINE>]" variable="strSECOND_LINE">
<tr>
<td rowspan=2>

!!<<intCUR_ENTRY>>
</td>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection1" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine1}!match[]else[0]]" variable=intSTART_LINE><$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_card_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection1"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strFIRST_LINE>> /></td>
</tr>
<tr>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection2" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine2}!match[]else[0]]" variable=intSTART_LINE>
<$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_second_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_second_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection2"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strSECOND_LINE>> /></td>
</tr>
</$list></$list></$list>
</table>
\end
\define glbl_compare_lines(ur_card_pk, ur_second_pk)
<$list filter="[{$ur_card_pk$}splitregexp[\n]count[]]" variable="intFIRST_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]]" variable="intSECOND_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]subtract<intFIRST_COUNT>]" variable="intSECOND_EXTRA">

[[$ur_card_pk$]] line count: <<intFIRST_COUNT>>

[[$ur_second_pk$]] line count: <<intSECOND_COUNT>>

''$ur_second_pk$'' excess line count: ''<<intSECOND_EXTRA>>''

<$macrocall $name=glbl_compare_lines_results_table ur_card_pk="$ur_card_pk$" ur_second_pk="$ur_second_pk$" ur_row_count=<<intSECOND_COUNT>> />
</$list>
</$list>
</$list>
\end

<!--
<$edit-text tiddler="$:/state/popup/CompareText1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>
<$edit-text tiddler="$:/state/popup/CompareText2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>

<<glbl_compare_lines "$:/state/popup/CompareText1" "$:/state/popup/CompareText2">>
-->

TiddlyWiki\Construct a Calendar

Extract Formatting Numbers TWCard
\define CalendarEntryDay(ur_ymd,ur_d,ur_cur_date)
<$list filter='$ur_ymd$ +[match[$ur_cur_date$]]'>
//''<span style="background-color:yellow">$ur_ymd$</span>''//<br>
</$list>
<$list filter='[prefix[$ur_ymd$]count[]match[0]]'>
<$list filter='$ur_ymd$ +[!match[$ur_cur_date$]]'>
$ur_ymd$<br>
</$list>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]match[1]]">
''d$ur_d$''<br><<currentTiddler>> entry<br>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]!match[0]!match[1]]">
''d$ur_d$''<br><<currentTiddler>> entries<br>
</$list>
\end

\define CalendarEntryMonth(ur_ym,ur_d,ur_cur_date)
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]!match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d0$ur_d$" ur_d="0$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d$ur_d$" ur_d="$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
\end

\define CalendarListDailyThings(day month year)
<$button class='tc-btn-invisible' style='width:100%;height:100%'>
<div style='height:100%;width:100%;position:relative;text-align:left;vertical-align:top;z-index=0'>

<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]!match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_ym="$year$m0$month$" ur_d="$day$"  ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_m="$year$m$month$" ur_d="$day$" ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>


</div>
</$button>
\end
\define date_list_entry(ur_num,ur_cur_date)
<$list filter="[[$ur_num$]match[$ur_cur_date$]]">
//''<span style="background-color:yellow">$ur_cur_date$</span>''//<br>
</$list>
<$list filter="[prefix[$ur_num$]count[]!match[0]]">
<$list filter="[[$ur_num$]!match[$ur_cur_date$]count[]!match[0]]">
$ur_num$<br>
</$list>
</$list>
<<list-links filter:"[prefix[$ur_num$]]" >>
\end
\define date_list_dayunit(ur_num,ur_cur_date)
<$list filter="$ur_num$0 $ur_num$1 $ur_num$2 $ur_num$3 $ur_num$4 $ur_num$5 $ur_num$6 $ur_num$7 $ur_num$8 $ur_num$9">
<$macrocall $name="date_list_entry" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list_daydec(ur_year_month,ur_num,ur_cur_date)
<$list filter="$ur_year_month$d0 $ur_year_month$d1 $ur_year_month$d2 $ur_year_month$d3 $ur_year_month$d4 $ur_year_month$d5 $ur_year_month$d6 $ur_year_month$d7 $ur_year_month$d8 $ur_year_month$d9">
<$macrocall $name="date_list_dayunit" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list(ur_year,ur_month)
<$calendar-month year="$ur_year$" month="$ur_month$" />

<$macrocall $name="date_list_daydec" ur_year_month="$ur_year$m$ur_month$" ur_num=<<currentTiddler>> ur_cur_date=<<now YYYYm0MMd0DD>> />
\end

TiddlyWiki\Core Macro Definition

Extract FileSystem TWCard
  • Title = mcr glbl_core_mcr_def
  • Tag = $:/tags/Macro
\define glbl_core_mcr_def(ur_macro_name)
<$list variable=cur_pk filter="""[[$:/core]get[text]split[define $ur_macro_name$(]butfirst[]split[\n\\end]first[]addprefix[define $ur_macro_name$(]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">
<$codeblock code=<<cur_pk>> />
</$list><!--cur_pk-->
\end
  • Show all Core macro names and source code
<$list variable=show_code_pk filter="[<currentTiddler>split[Draft of]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-checkShowCode]]">
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>

<$list variable=cur_def_text filter="[[$:/core]get[text]split[define ]!prefix[{]!prefix[the]sort[]]">
<$list variable=cur_macro_name filter="[<cur_def_text>split[(]first[]]">
<$list variable=cur_end_text filter="""[<cur_def_text>split[\n\\end]first[]addprefix[define ]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">

!! <<cur_macro_name>>
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]match[yes]]"><$codeblock code=<<cur_end_text>> />
</$list><!--cur_showcode_text-->

</$list><!--cur_end_text-->
</$list><!--cur_macro_name-->
</$list><!--cur_def_text-->
</$list><!--show_code_pk-->

TiddlyWiki\CSS Classes

CSSCode Formatting TWCard

New Card page

.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}

Note: The @@ directive must include the leading period (.) to select a CSS class

@@.alternating-rows
<table>
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

TiddlyWiki\CSS without classes

CSSCode Formatting TWCard

Apply stylesheet to all cards

.tc-tiddler-body {
  word-break: normal; 
  word-wrap: break-word;
  white-space: pre-wrap;
} 
  • Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

Apply stylesheet to cards with specific tag linewrap

[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
  • Note: Only cards with the linewrap tag will use this stylesheet change

Apply Styles to In-line Text

  • Start a text block with @@ and the CSS styles with no spaces

Sample Code:

@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line

Result:

These are
separate lines
here

This is one big line
  • or start in the middle of a text block

Sample Code:

This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.

Result:

This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.

TiddlyWiki\Data Tiddler

AssignVariable FileSystem TWCard

Type = application/x-tiddler-dictionary

3:a
2:b
3:c

See list of unique indexes:

<$list variable=cur_key filter="[[UrPK]indexes[]]"><<cur_key>>: 
<$list variable=cur_val filter="[[UrPK]getindex<cur_key>]"><<cur_val>><br>
</$list><!--cur_val-->
</$list><!--cur_key-->

Use one value (last one if an index is duplicated):

-{{UrPK##3}}-

VBNetCode\Text file to JSON Lines


TiddlyWiki\Date Part

Extract Formatting Numbers TWCard

Tag = $:/tags/Macro

\define glbl_dt_ddd()
<div style="clear:right;float:right;background-color:aquamarine;"><<now "YYYYm0MMd0DD DDD pm0hh12\m0mm">></div>
<$list filter="[<currentTiddler>split[Draft of ']join[]split[ ]first[]split[m]join[]split[d]join[]]">
<$view field="title" format="date" template="[UTC]DDD" />
</$list>
\end
TokenSubstituted Value
DDDDay of week in full (eg, "Monday")
dddShort day of week (eg, "Mon")
DDDay of month
0DDAdds a leading zero
DDthAdds a suffix
WWISO-8601 week number of year
0WWAdds a leading zero
MMMMonth in full (eg, "July")
mmmShort month (eg, "Jul")
MMMonth number
0MMAdds leading zero
YYYYFull year
YYTwo digit year
wYYYYFull year with respect to week number
wYYTwo digit year with respect to week number
hhHours
0hhAdds a leading zero
hh12Hours in 12 hour clock
0hh12Hours in 12 hour clock with leading zero
mmMinutes
0mmMinutes with leading zero
ssSeconds
0ssSeconds with leading zero
XXXMilliseconds
0XXXMilliseconds with leading zero
am or pmLower case AM/PM indicator
AM or PMUpper case AM/PM indicator
TZDTimezone offset
\xUsed to escape a character that would otherwise have special meaning
[UTC]Time-shift the represented date to UTC. Must be at very start of format string

TiddlyWiki\Decimal To Hex

Extract Numbers TWCard

Name = mcr glbl_dec_to_hex5
Tag = $:/tags/Macro

\define glbl_dec_to_hex5(ur_code)
<$list filter="[[$ur_code$]divide[16]divide[16]divide[16]divide[16]floor[]]" variable=lvl_x4>
<$list filter="[<lvl_x4>multiply[16]multiply[16]multiply[16]multiply[16]]" variable=lvl_d4>
<$list filter="[[$ur_code$]subtract<lvl_d4>divide[16]divide[16]divide[16]floor[]]" variable=lvl_x3>
<$list filter="[<lvl_x3>multiply[16]multiply[16]multiply[16]]" variable=lvl_d3>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>divide[16]divide[16]floor[]]" variable=lvl_x2>
<$list filter="[<lvl_x2>multiply[16]multiply[16]]" variable=lvl_d2>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>divide[16]floor[]]" variable=lvl_x1>
<$list filter="[<lvl_x1>multiply[16]]" variable=lvl_d1>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>subtract<lvl_d1>]" variable=lvl_xrem>
<$list filter="[range[15]butfirst[9]match<lvl_x4>add[55]] [range[10]subtract[1]match<lvl_x4>add[48]]" variable=lvl_h4>
<$list filter="[range[15]butfirst[9]match<lvl_x3>add[55]] [range[10]subtract[1]match<lvl_x3>add[48]]" variable=lvl_h3>
<$list filter="[range[15]butfirst[9]match<lvl_x2>add[55]] [range[10]subtract[1]match<lvl_x2>add[48]]" variable=lvl_h2>
<$list filter="[range[15]butfirst[9]match<lvl_x1>add[55]] [range[10]subtract[1]match<lvl_x1>add[48]]" variable=lvl_h1>
<$list filter="[range[15]butfirst[9]match<lvl_xrem>add[55]] [range[10]subtract[1]match<lvl_xrem>add[48]]" variable=lvl_hrem>
<$wikify name=str_hex_out text="0x&#<<lvl_h4>>;-&#<<lvl_h3>>;&#<<lvl_h2>>;&#<<lvl_h1>>;&#<<lvl_hrem>>;" >
<<str_hex_out>>
</$wikify>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
\end

TiddlyWiki\Delete All Cards with Tag

AssignVariable FileSystem TWCard
<$button>
<$list filter="[tag[ARTICLE]]"><$action-sendmessage $message=tm-delete-tiddler $param=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards with Confirmation
</$button>

<$button>
<$list filter="[tag[ARTICLE]]"><$action-deletetiddler $tiddler=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards without Confirmation
</$button>

<$button>
<$list filter="[tag[DOC]]" variable=doc_pk><$list filter="[<doc_pk>fields[]prefix[e]]" variable=field_pk2><$action-deletefield $tiddler=<<doc_pk>> $field=<<field_pk2>> /></$list></$list>
Del fields starting with `E` in DOC tagged Cards
</$button>

TiddlyWiki\DivPop btn

FileSystem TWCard UserAction

DivPop.svg

Tag = $:/tags/ViewToolbar

\define divpop_current(ur_ref)
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text="$ur_ref$"/>
<$action-sendmessage $message="tm-close-tiddler" $param="pop_right"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{DivPop.svg}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text="Popup over Sidebar"/></span>
</$list>
</$button>
\end

<$list filter="[all[current]]">
<$macrocall $name=divpop_current ur_ref=<<currentTiddler>> /> 
</$list>

TiddlyWiki\DivPop glbl

FileSystem TWCard UserAction

Tag = $:/tags/BelowStory

<$list filter="[{$:/state/popup/DivPopTitle}is[tiddler]]">
<div style="
position: fixed;
top: 0px;
right: 0px;
width: 350px;
border: 3px solid;
background: white;
bottom: 0%;
">
<div style="overflow-y: scroll; height: 100%;">
<$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
close
</$button>
<$tiddler tiddler=<<currentTiddler>> >
<$transclude mode="block" />
</$tiddler>
</div>
</div>
</$list>

TiddlyWiki\Embed Font

FileSystem Formatting Text TWCard

[https://tiddlywiki.narkive.com/bS0CgWKQ/tw-tw5-how-to-embed-a-font-using-font-face-and-data-url]
- Visit: http://www.fontsquirrel.com/tools/webfont-generator
- Upload your font file (".ttf", ".eot", ".woff", etc)
- Select option "Expert"
- Check the option case at CSS >> Base64 Encode
- Generate your webkit -> Downloads file

[stylesheet.zip file]
- Unpack ZIP file -> Downloads file

[stylesheet.css]
- Note: The file's content in Base64 encoded

[Wiki file]
- Drag-drop file to import -> Creates Card
- [styleshee.css Card]
- Make sure the field font-family is what you want
- Tag = $:/tags/Stylesheet
- Tiddler type = Plain text (text/plain)
- Create a new Card and use the font


TiddlyWiki\Encrypt file

AssignVariable FileSystem TWCard

[Wiki file]
- [Sidebar, Tools tab]
- Click button Set Password -> Opens dialog
- Password = UrPasswordText
- Repeat password = UrPasswordText
- Click button Set Password -> Closes dialog

[keyboard action SaveAllChanges]
- [<$action-sendmessage $message="tm-download-file"]
- Comment out this tag to keep the HTML Wiki version from being exported
- Save the Wiki file

- Note: The password will be required to start the Wiki application when you open the Wiki file


TiddlyWiki\External Link organization

FileSystem Formatting TWCard
  • Create one Card for each external link in this format
    • Title always starts with ext and a space, then the external link description
    • Tagged as EXT
    • Contains one line in this format:
[ext[ur_url]]
  • Reference the Card with the ext macro, but don't include the ext prefix or the leading space
  • The link is shown, and there will be -> on the right side of the Card window
  • This flags links that will open in a new tab, and allows you to easily open the ext Card and change the saved link
<<ext "UrExternalLinkDiscption">>
  • Global macro
\define ext(ur_extcard_pk)
{{ext $ur_extcard_pk$}}<div style="float:right">[[_|ext $ur_extcard_pk$]]</div>
\end

TiddlyWiki\Filter Operators

CodeLibrary Filter TWCard

Math

abs - calculate the absolute value of a list of numbers
add - treating each input title as a number, add to each the numeric value of the operand
ceil - rounds a list of numbers up to the next largest integer
divide - treating each input title as a number, divide them by the numeric value of the operand
exponential - convert each number to exponential notation with N digits
fixed - convert each number to fixed point notation with N digits after the decimal point
floor - rounds a list of numbers to the largest integer less than or equal to each number
max - treating each input title as a number, take the maximum of its value and the numeric value of the operand
maxall - find the largest of a list of numbers
min - treating each input title as a number, take the minimum of its value and the numeric value of the operand
minall - find the smallest of a list of numbers
multiply - treating each input title as a number, multiply it by the numeric value of the operand
negate - calculate the negation of a list of numbers
precision - convert each number to a string with N significant digits
product - produce the product of the input numbers
remainder - treating each input title as a number, return the remainder when divided by the numeric value of the operand
round - rounds a list of numbers to the nearest integer
sign - return -1, 0 or 1 for a list of numbers according to whether each number is negative, zero, or positive
subtract - treating each input title as a number, subtract from each the numeric value of the operand
sum - produce the sum of the input numbers
trunc - truncates a list of numbers to their integer part, removing any fractional part
untrunc - rounds a list of numbers to the next integer with largest absolute value, that is, away from zero


TiddlyWiki\Fonts via URL

FileSystem Formatting Text TWCard
<link href='https://fonts.googleapis.com/css?family=Playfair Display' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Sofia' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Alex Brush' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Akronim' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Annie Use Your Telescope' rel='stylesheet'>

@@font-family: 'Playfair Display';
!'Playfair Display'  1234567890 ABC abc
@@

@@font-family: 'Sofia';
!'Sofia'  1234567890 ABC abc
@@

@@font-family: 'Alex Brush';
!'Alex Brush'  1234567890 ABC abc
@@

@@font-family: 'Akronim';
!'Akronim'  1234567890 ABC abc
@@

@@font-family: 'Annie Use Your Telescope';
!'Annie Use Your Telescope'  1234567890 ABC abc
@@

TiddlyWiki\Global Card Footer

FileSystem Formatting TWCard

Every Card shows the Wikified content of the Card content, followed by the Wikified content of every Card with the tag $:/tags/ViewTemplate.

Example Footer Text

Create a new Card

template Global Footer

Any Text Here

Add the tag:

And then every Card will show the words "Any Text Here" at the bottom of the Card.

Example Footer Home Button

Create a new Card

template Home Button

<div style="float:right">{{$:/core/ui/Buttons/home}}</div>

Add the tag:

And then every Card will show the "Home" icon at the bottom-right of the Card.


TiddlyWiki\Global Macro

FileSystem TWCard

Tag = $:/tags/Macro


TiddlyWiki\Group Totals

CodeLibrary Filter Numbers TWCard
unique_groups()
- find list of titles with UrAttribute
    - [has[UrAttribute]]
- split by the prefix before the first hyphen
    - [<currentTiddler>split[-]nth[1]]
- return each title's prefix followed by a space
    - ><<currentTiddler>> <

unique_counts()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces
    - [<ugrp>split[ ]
- ignore white-space only entries, and sort the rest alphabetically
    - !match[]sort[]
- use "each:value" to get the unique title prefixes in the list
    - each:value[]]
- for each unique title prefix, get a count of titles with UrAttribute
    - [has[UrAttribute]prefixcount[]]

count_size()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces, ignore white-space, sort, use "each:value", store as ur_entry
    - [<ugrp>split[ ]!match[]sort[]each:value[]]
    - ur_entry=<<currentTiddler>>
- for each unique title prefix, only continue where the count of titles with UrAttribute matches the parent unique count
    - [has[UrAttribute]prefix<ur_entry>count[]match[$(currentTiddler)$]]
- find all the titles with the unique title prefix, and return a "1" for each entry
    - [has[UrAttribute]prefix]">1 <

main()
- create a new variable ucnt with the list of title prefixes from unique_counts()
    - <$wikify name=ucnt text=<<unique_counts>>
- split the new variable by spaces, ignore white-space, sort, use "each:value"
    - [split[ ]trim[]!match[]sort[]each:value[]]
- For each unique count,
    - list the entry
    - sum the number of entries returned from count_size() divided by the unique count
\define unique_groups()
<$list filter="[has[eng-vocab]]"><$list filter="[<currentTiddler>split[-]nth[1]]"><<currentTiddler>> </$list></$list>
\end
\define unique_counts()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]">
<$list filter="[has[eng-vocab]prefix<currentTiddler>count[]]"><<currentTiddler>> </$list>
</$list>
</$wikify>
\end
\define count_size()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]"><$vars ur_entry=<<currentTiddler>> >
<$list filter="[has[eng-vocab]prefix<ur_entry>count[]match[$(currentTiddler)$]]">
<$list filter="[has[eng-vocab]prefix<ur_entry>]">1 </$list>
</$list>
</$vars></$list>
</$wikify>
\end
<$wikify name=ucnt text=<<unique_counts>> >
<$list filter="[<ucnt>split[ ]trim[]!match[]sort[]each:value[]]">
ASLSJ Prefix Groups with <<currentTiddler>> words -
<$wikify name=usize text=<<count_size>> >
<$list filter="[<usize>split[ ]trim[]!match[]sum[]divide<currentTiddler>]"><<currentTiddler>><br>
</$list>
</$wikify>
</$list>
</$wikify>

TiddlyWiki\Hard Line Breaks

Formatting Text TWCard

HTML normally ignores line breaks. TiddlyWiki uses HTML, and includes a way to stop ignoring line breaks.

[TiddlyWiki editor] - Type three double-quotes (""") and press enter to ignore line breaks below this point - The (""") does not show up in the output

Three double-quotes will start a hard line breaks section

"""
line one blends into line two continues

"""
line three stops
line four starts
"""

line one blends into line two continues

line three stops
line four starts

HTML Preformatted text with Sans-Serif font

<pre style="font-family: sans-serif;">line three stops line four starts</pre>

line three stops
line four starts


TiddlyWiki\Hidden on Static File

FileSystem Formatting TWCard

Hide section when exported to static HTML file

<$list filter="[<tv-config-toolbar-icons>match[no]]">

TiddlyWiki\iFrame

Extract FileSystem HTMLCode TWCard

Use an iFrame to run JavaScript in a TiddlyWiki

>iframe src="javascript:newWindow='';var ...

- just javascript:newWindow=var ... did not compile. An empty string is a work-around.

Alternative output: use alert instead of document.write

alert(strTEXT);"/>

How to reference an external HTML file in a tiddler

>iframe src=...  scrolling=yes style="border-style:none;height:100%;width:100%">
>/iframe>

- A self-closing tag does not allow remaining html code to be displayed - ALWAYS specify a closing >/iframe> tag

TW Macro to show iframe and link

>div style='float:right'>[ext[_ |$ur_pk$.txt.html]]
>/div>
>iframe src='$ur_pk$.txt.html'>
>/iframe>

- $macrocall $name=iframe_txt ur_pk= currentTiddler

<iframe src="javascript:newWindow='';var qs = '&quot;';var qt = '&apos;';

var objFRAME = document.createElement('iframe');
objFRAME.setAttribute('id', 'innerFrame');
objFRAME.setAttribute('src', 'http://www.google.com/');
document.body.appendChild(objFRAME); 
var objTEST = objFRAME;
var strTEXT = '';
if (objTEST===undefined) {
strTEXT = 'undef obj';
} else if (objTEST===null) {
strTEXT = 'null obj';
} else {
var intSEQ = 0;
var strNAME;
for (strNAME in objTEST) {
intSEQ += 1;
strTEXT += ' ; ' + strNAME;
}
strTEXT = 'olen ' + intSEQ + strTEXT;
}
document.write(strTEXT);"></iframe>

alert(strTEXT);"/>

<iframe src='iframe.scrE2.txt' height=100% width=100% scrolling=yes frameborder=no></iframe>


\define iframe_txt(ur_pk)
<div style="float:right">[ext[_ |$ur_pk$.txt.html]]</div>
<iframe src='$ur_pk$.txt.html' scrolling=yes style="border-style:none;height:100%;width:100%"></iframe>
\end

TiddlyWiki\Ignore WikiText formatting

Formatting Text TWCard

Use the TextWidget to ignore WikiText formatting

  • widget name = $text
  • text attr = `still black colored text`

Sample code

<$text text="`still black colored text`" />

Results:

`still black colored text`

Use the Rules card pragma to ignore WikiText formatting

  • [New card]
  • Put \rules only at the top of the card text

Sample code

\rules only
`still black colored text`

Results:

`still black colored text`

Use the Card Datatype to ignore WikiText formatting

  • [New card]
  • type field = text/plain

Sample code

`still black colored text`

Results:

`still black colored text`

TiddlyWiki\Image

Formatting TWCard

Link an image in a Tiddler with 500px width
- Have image tiddler
- Have text tiddler
- Apply image to text tiddler at 500px width

[New tiddler]
- title = mcr img_link
- tag = $:/tags/Macro
- text field code

\define img_link(ur_pk)
@@max-width:500px;
[img [$ur_pk$]]
@@
\end

[Text tiddler]
- $macrocall $name=img_link ur_pk= currentTiddler


TiddlyWiki\Image link opens Card

FileSystem TWCard UserAction

Tag = $:/tags/Macro

\define glbl_image_high(ur_image_pk, ur_size:200)
<$link to="$ur_image_pk$">[img height=$ur_size$px [$ur_image_pk$]]</$link>
\end
\define glbl_image_wide(ur_image_pk, ur_size:500)
<$link to="$ur_image_pk$">[img width=$ur_size$px [$ur_image_pk$]]</$link>
\end

TiddlyWiki\Import Macros

FileSystem TWCard
\import [[mcr date_list]]

TiddlyWiki\Javascript Calculation in Bookmarklet

Bookmarklet Extract JavaScriptCode TWCard
  • Click the button to copy the text to a javascript bookmarklet
  • Open a new tab
  • Type the letter "j" in the address bar, paste in the clipboard text, and press enter
  • The Javascript alert box shows the message
\define glbl_copyto_js_bookmarklet(ur_js_code)
<pre>$ur_js_code$</pre>
<$macrocall $name="copy-to-clipboard" src="""avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){const el = newWindow.document.createElement('textarea');const ur_str='$ur_js_code$';try {el.value =eval(ur_str)}catch(err) {el.value = err.message;}; newWindow.document.body.appendChild(el); el.select();void(newWindow.focus());}""" />
\end

<!--|v
<<glbl_copyto_js_bookmarklet """parseInt("FF",16).toString(10);""">>
^|-->

TiddlyWiki\Keep words together on one line

Formatting Text TWCard

Use CSS white-space tag

  • The CSS white-space:nowrap; disables normal text wrapping
  • This is useful when you have several smaller phrases that should not be separated visually onto different lines
  • Note: This can make the line extend past the edge of the browser window, requiring scrolling to see the rest

Sample Code that can split phrases

A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)

Results:

A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)

Sample Code that can keeps short phrases together

@@white-space:nowrap;A code line (1)@@ @@white-space:nowrap;A code line (2)@@ @@white-space:nowrap;A code line (3)@@ @@white-space:nowrap;A code line (4)@@ @@white-space:nowrap;A code line (5)@@ @@white-space:nowrap;A code line (6)@@ @@white-space:nowrap;A code line (7)@@ @@white-space:nowrap;A code line (8)@@ @@white-space:nowrap;A code line (9)@@ @@white-space:nowrap;A code line (10)@@ @@white-space:nowrap;A code line (11)@@ @@white-space:nowrap;A code line (12)@@ @@white-space:nowrap;A code line (13)@@ @@white-space:nowrap;A code line (14)@@

Results:

A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)


TiddlyWiki\Keyboard Shortcut

CodeLibrary TWCard UserAction

Pre-requisites

  • You need a ur_message_to_send to replace in the below steps
    • tm-home is an example message that TiddlyWiki can do
  • You need a ur_card_pk to replace in the below steps
    • It should describe the desired action

Setup keyboard shortcut

[New Card]

[New Card]

alt-H

[New Card]

((ur_card_pk))
  • Main Body Text =
<$action-sendmessage $message="ur_message_to_send"/>

TiddlyWiki\List Links from Numbered Fields

Filter Numbers TWCard
<ol>
<$list filter="[<currentTiddler>fields[]prefix[e]sort[]]" variable=lookup_name>
<$list filter="[<currentTiddler>get<lookup_name>]" variable=ref_card_pk>
<$list filter="[<ref_card_pk>get[img]else[]]" variable=ref_img_pk>
<li><$link to=<<ref_card_pk>> />@@float: right;overflow: auto;vertical-align: top;padding-left: 10px;<$image width=200px source=<<ref_img_pk>> />@@<div style="clear:both;"></div></li>
</$list>
</$list>
</$list>
</ol>

TiddlyWiki\List Links of Prefixed Cards

Filter TWCard
<ol>
<$list filter="[<currentTiddler>addsuffix[\]]">
<$list filter="[all[tiddlers]prefix<currentTiddler>sort[]]">
<li><$link to=<<currentTiddler>> /></li>
</$list>
</$list>
</ol>

TiddlyWiki\List Links standard

Filter TWCard
<<list-links filter:"[tag[DOC]field:level[1]sort[title]] [tag[DOC]field:level[]sort[title]]">>

TiddlyWiki\List Widget

Filter TWCard

Content and Attributes

The content of the <$list> widget is an optional template to use for rendering each tiddler in the list.

The action of the list widget depends on the results of the filter combined with several options for specifying the template:

  • If the filter evaluates to an empty list, the text of the emptyMessage attribute is rendered, and all other templates are ignored
  • Otherwise, if the template attribute is specified then it is taken as the title of a tiddler to use as a template for rendering each item of the list
  • Otherwise, if the list widget content is not blank, it is used as a template for rendering each item of the list
  • Otherwise, a default template is used consisting of a <span> or <div> element wrapped around a link to the item
AttributeDescription
filterThe tiddler filter to display
templateThe title of a template tiddler for transcluding each tiddler in the list. When no template is specified, the body of the ListWidget serves as the item template. With no body, a simple link to the tiddler is returned.
editTemplateAn alternative template to use for DraftTiddlers in edit mode
variableThe name for a variable in which the title of each listed tiddler is stored. Defaults to currentTiddler
emptyMessageMessage to be displayed when the list is empty
storyviewOptional name of module responsible for animating/processing the list
historyThe title of the tiddler containing the navigation history

Additional Notes and Edge Cases

  • If the filter attribute is not present then a default of [!is[system]sort[title]] is used
  • If the list widget is completely empty (ie only whitespace between the opening and closing tags), then it behaves as if the content were a DIV or a SPAN containing a link to the current tiddler (it’s a DIV if the list widget is in block mode, or a SPAN if it is in inline mode)
  • If the template attribute is not present then the content of the list widget will be used as the template, unless the widget is completely empty in which case a default template is used

TiddlyWiki\Local Video or Audio Files

Audio CodeLibrary FileSystem TWCard Video
<video width="320" height="180"
poster="video\Frozen Sleep - Cortana Tribute by Malukah.png"
controls preload="none">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.webm" type=
"video/webm">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.ogv" type=
"video/ogg">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.mp4" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
<audio controls preload="none">
<source src="audio\Frozen-Sleep-Malukah.ogg" type="audio/ogg">
<source src="audio\Frozen-Sleep-Malukah.mp3" type="audio/mp3">
<p>Your browser does not support the HTML 5 audio tag.</p>
</audio>

TiddlyWiki\Pagination

Filter Formatting Text TWCard
\define page_next()
<$list variable="filter_prev_page" filter="[<page_pk>get[text]!match[0]!match[]]">
<$button style="margin-left:30px">
<$action-setfield $tiddler=<<page_pk>> text=""/>
First page
</$button>

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>subtract[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/></$list>
Previous page
</$button>
</$list><!--filter_prev_page-->

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>add[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/><$action-navigate $to=<<card_pk>> $scroll="yes"/></$list>
Next page
</$button><br>
<!--***page_next***-->
\end
<$list variable="card_pk" filter="[<currentTiddler>]">
<$list variable="popup_pk" filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]">

<$list variable="page_pk" filter="[<popup_pk>addsuffix[-cur_page]]">
<$list variable="cur_page_skip" filter="[<page_pk>get[text]!match[]else[0]]">
<$list variable="cur_page_num"filter="[<cur_page_skip>add[1]]">
<$list variable="cur_page_through" filter="[<cur_page_num>subtract[1]add[10]]">
<<page_next>>

<$list variable="subdir_count" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]count[]]">

Subdirectories <<cur_page_num>> through <<cur_page_through>>

Number of subdirectories: <<subdir_count>><br>
<$list variable="cur_subdir_path" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]butfirst<cur_page_num>first[10]]">

<$list variable="raw_image_count" filter="[{File List Data}splitregexp[\n]prefix<cur_subdir_path>uppercase[]suffix[.JPG]count[]addprefix[ (]addprefix<cur_subdir_name>addsuffix[ photo]]">
<<raw_image_count>>
</$list><!--raw_image_count-->

</$list><!--cur_subdir_path-->
</$list><!--subdir_count-->
<<page_next>>
</$list><!--cur_page_through-->
</$list><!--cur_page_num-->
</$list><!--page_pk-->
</$list><!--popup_pk-->
</$list><!--card_pk-->

TiddlyWiki\Popup State Clear All

AssignVariable CodeLibrary TWCard
<$list filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]" variable="popup_pk">
<$button>
<$list filter="[all[tiddlers]prefix<popup_pk>has[text]]" variable=del_pk><$action-deletefield $tiddler=<<del_pk>> $field="text"/></$list>
Show All
</$button><br>

</$list>

TiddlyWiki\Published Tools

CodeLibrary TWCard

https://dynalist.io/d/zUP-nIWu2FFoXH-oM7L7d9DM#z=zdF80rIaJ79W5P0IGsjYIjkD

[Ace editor](http://innoq.tiddlyspot.com/)
[ActionIncrement widget](https://skeeve.github.io/tw5-plugins/) - The action-increment widget is an action widget that retrieves a value from a text reference. It will then increase the first digit-sequence found in that text and store it.
[Ad-Hoc Macro](https://tobibeer.github.io/tb5/#Ad-Hoc%20Macro) - evaluate any text as an ad-hoc macro even passing variables.
[Amazon Web Services Plugin](https://tiddlywiki.com/#OfficialPlugins) - provides several tools for working with Amazon Web Services **(official TW plugin)**
[Delay Actions](https://groups.google.com/forum/#!topic/tiddlywiki/z7SGLAPODW8), defer the execution of action widgets for a set amount of time
[CouchDB adaptor](https://github.com/wshallum/couchadaptor)
[Count (tobibeer)](http://tobibeer.github.io/tw5-plugins/#count) - A filter to count titles or compare against a specified count
[Demo Code Macro](http://ooktech.com/jed/ExampleWikis/DemoCodeMacro/) - This is an attempt to make a macro that can be used to demonstrate wikitext code fragments in an interactive way.
[dom (tobibeer)](http://tobibeer.github.io/tw5-plugins/#dom) - retrieve text or attributes from dom nodes
[eval (tobibeer)](http://tobibeer.github.io/tw5-plugins/#eval) - Evaluate expressions, compute and compare tiddler properties and data
[Fargo.io integration](http://blog.jeffreykishner.com/2014/01/24/note-taking-bookmarklets-for-fargoio-and-tiddlywiki-.html)
[Global macros, instructions on how to make](http://tw5magick.tiddlyspot.com/)
[Highlight plugin](https://tiddlywiki.com/plugins/tiddlywiki/highlight/#%24%3A%2Fplugins%2Ftiddlywiki%2Fhighlight) **(official TW plugin)** - description: Plugin that activates syntax highlighting of code blocks using v8.8.0 of highlight.js from Ivan Sagalaev. demo [here](https://tiddlywiki.com/plugins/tiddlywiki/highlight/)
[HTAlink](http://welford.github.io/) - Will only work in offline hta editions of this page. Launches external links in your default browser and not IE
[ifAisB](https://tid.li/tw5/hacks.html) - This macro allows to test if a value A – a variable or a transcluded value – matches a value B and to react accordingly. It works almost like an if-then-else statement.
[IfTid Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the existence of a tiddler (or field) and to send different widget messages based upon the existence of this tiddler (or field.)
[IfTref Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the value of a TextReference and to send different widget messages based upon whether this value matches the value specified by the 'value=' attribute.
[Incremental load command](http://malsandbox.tiddlyspot.com/) - only loads tiddlers that either don't already exist in the tiddlers folder, or have a newer modified date than the existing tiddler.
[Javascript macros in wikitext](http://tw5magick.tiddlyspot.com/)
[JSON editor (btheado)](http://btheado.github.io/jsoneditor.html)
[JSON editor (bjtools)](http://bjtools.tiddlyspot.com/)
[JsonMangler](https://joshuafontany.github.io/TW5-JsonMangler/) - This plugin changes the methods tiddlywiki uses to retrieve and set values in json data tiddlers. It does this in a way that aims for backwards compatibility.

[keyboard-snippets plugin](http://braintest.tiddlyspot.com/#keyboard-snippets)
[LetWidget](http://tiddlystuff.tiddlyspot.com/) - The LetWidget is an enhancement of the SetWidget.
[mforth](https://quaraman.de/tw/mforth.html) - It is a forth like language in a tiddlywiki macro. Forth operates with Reverse Polish Notation (RPN for short).
[Mousetrap](http://welford.github.io/) - simple library for handling keyboard shortcuts in Javascript.
[muut integration](http://ooktech.com/jed/ExampleWikis/TiddlyWiki-muut/)
[Nodewebkitsaver plugin](http://ooktech.com/jed/ExampleWikis/SetFilters/#%24%3A%2Fplugins%2FOokTech%2FSetFilters) - provides a saver module for saving changes when using [TiddlyWiki](http://ooktech.com/jed/ExampleWikis/SetFilters/#TiddlyWiki) directly under NW.js (previously known as node-webkit).
[Pack as plugin](http://braintest.tiddlyspot.com/#Pack%20as%20plugin) - Beta version
[Pan widget](http://muritest.tiddlyspot.com) - This widget is touch sensitive. It is able to trigger actions as the start and end of pans. Multiple differntial pans are possible.
[Persistent-states](https://wikilabs.github.io/#persistent-states) and [Remove-states](https://wikilabs.github.io/#remove-states)
[pick Plugin](https://skeeve.github.io/tw5-plugins/) - The pick plugin is a set of two filters and one widget to help extracting data from your TiddlyWiki file.
[PluginSize](https://tid.li/tw5/plugins.html#%24%3A%2Fplugins%2Ftelmiger%2FPluginSize:%24%3A%2Fplugins%2Ftelmiger%2FPluginSize) - This plugin calculates the size of all installed plugins, including themes and languages.
[PluginDevelopment](https://github.com/inmysocks/PluginDevelopment) – Scripts to help you create plugins and plugin libraries for node.js
[pv5](http://pv5.tiddlyspot.com/) - testing params and variables
[random (tobibeer)](http://tobibeer.github.io/tw5-plugins/#random) - A filter to return one or more random titles
[ReplacePragma](http://tiddlystuff.tiddlyspot.com/)
[Save trail plugin](https://tiddlywiki.com/#OfficialPlugins) - This plugin causes TiddlyWiki to continuously download (as a JSON file) the contents of any tiddler that is manually changed by any of several means **(official TW plugin)**
[setvars (tobibeer)](http://tobibeer.github.io/tw5-plugins/#setvars) - Set multiple, complex variables based on attributes, filters, or conditionals
[Shuffle filter operator](https://mklauber.github.io/tw5-plugins/#Shuffle%20Operator) - implements a new filter operator called Shuffle. This operator takes the input list and randomizes the order of the list. If no parameter is provided, the list order is random every time.
[SPilot4Tw](https://www.quaraman.de/tw/pilot.html) - A programming language that can be included as Tiddlywiki plugin.
[Startup Actions demo](http://ooktech.com/jed/ExampleWikis/StartupActions/) - A plugin to add startup scripts to TiddlyWiki
[style (tobibeer)](http://tobibeer.github.io/tw/style/#GettingStarted) - This wiki introduces you to using your desktop browser to inspect the styles applied to elements in TiddlyWiki and permanently change them.
[Three.js](http://rboue.tiddlyspot.com/#Three.js%2Fintroduction) - 3D modeling
[TiddlyWiki5 Coding](http://cjhunt.github.io/) - These pages document aspects TiddlyWiki5 programming, sharing "lessons learned" to help developers to get started with TiddlyWiki5 customization and extension. (FYI - 4 years old)
[Tinka](https://tinkaplugin.github.io/) - Create and modify plugins in the browser.
[Trace-variable example](http://eucaly-tw5.tiddlyspot.com/#trace-variable%20Example) - no clue what this is.
[Trigger Actions Demo](http://ooktech.com/jed/ExampleWikis/TriggerActions/)
[Tutorial Maker with HopScotchjs](https://cdn.rawgit.com/abesamma/TW5-tutorial-maker-plugin/29c31124/Demo.html) - a plugin that allows TW5 developers to create interactive product tutorials for their tiddlywiki projects, to guide new users.
[TW Components](https://tw-scripts.github.io/TW-Components/) - A component is a group of TW macros and tiddlers create a visual element for complex processes. The ultimate objective of TW components is to create objects which can simply by used by TW programmer to create complex plugins or codes.
[twexe - run exe's from hta files](https://github.com/welford/twexe) - only works in offline hta versions of TW. It lets you register and run exes from tiddlywiki


TiddlyWiki\Recently Changed Cards

CodeLibrary Filter TWCard
<<timeline limit:30 format:"YYYY-0MM-0DD">>

TiddlyWiki\Regular Expression

Filter Text TWCard
<!--|v
Split at Regular Expression skips everything before the first period -> `.12`,  `.1` and `.or.maybe.1`
^|-->

<$vars re="^[^\.]*">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>

<!--|v
Split at Regular Expression skips everything before the last period -> `1`,  `1` and `1`

Each:Value gets the unique list of entries -> `2` and `1`

Sort orders them numberically
^|-->

<$vars re="^.*\.">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>!match[]each:value[]sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>


<!--|v
Split
^|-->

<!--<$vars re="^[^\.]*"> skip up to first period excluded-->
<!--<$vars re="^.*\."> skip up to first period included-->
<$vars card_pk="File List Data" re="^.*\.">
<$list variable="cur_file_ext" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.gif(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.jpeg(?i)]] [<card_pk>get[text]splitregexp[\n]regexp[\.jpg$(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.png(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.tif(?i)]] +[splitregexp<re>!match[]each:value[]sort[]addprefix[.]]">
<$list variable="file_ext_count" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]suffix<cur_file_ext>count[]]">

<<cur_file_ext>>: <<file_ext_count>> files
</$list><!--file_ext_count-->
</$list><!--cur_file_ext-->
</$vars>

TiddlyWiki\Reveal Section and Copy Data

AssignVariable Formatting Text TWCard

Title = mcr T1Reveal

\define t1cb(UrContent)
<$list filter="[[$UrContent$]!match[]]">
$UrContent$
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
\end
\define t1reveal(UrPK UrSeq UrContent)
<$list filter="[[$UrContent$]!match[]]">
<br>
<$reveal type="nomatch" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="show">,,$UrSeq$,,</$button>
</$reveal>
<$reveal type="match" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="hide">^^$UrSeq$^^</$button><br>
"""
$UrContent$
"""
</$reveal>
<$list filter="[[$UrSeq$]match[Pwd]]">
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
</$list>
\end

TiddlyWiki\Save Wiki and Export HTML

Browser CodeLibrary Extract TWCard
\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.htm"
/>
<$action-sendmessage $message="tm-download-file"
$param="$:/core/templates/exporters/StaticRiver" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
exportFilter="""[all[tiddlers]tag[INDEX]sort[title]][all[tiddlers]!tag[EXTLINK]!tag[INDEX]!tag[META]!prefix[Draft of]!is[image]!is[tag]!is[system]sort[title]]"""/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.htm]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>

TiddlyWiki\Search all Fields

Filter Text TWCard
<$vars search_text_pk="$:/state/popup/SearchAllFields">
<$list variable=show_code_pk filter="[<search_text_pk>addsuffix[-checkShowCode]]">
<$list variable=skip_system_pk filter="[<search_text_pk>addsuffix[-checkSkipSystem]]">
<$edit-text tiddler=<<search_text_pk>> field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler=<<skip_system_pk>>> Skip System </$checkbox><br>
<br>

<$list variable=cur_search_text filter="[<search_text_pk>get[text]addsuffix[(?i)]!match[]]">
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]else[no]]">
<$list variable=cur_skipsystem_text filter="[<skip_system_pk>get[text]else[yes]match[yes]count[]]">

<!--Card titles-->
<$list variable=cur_pk filter="[regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_skipsystem_text>] [<cur_pk>!is[system]count[]] +[sum[]match[1]]">

<$link to=<<cur_pk>> />: title
</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

<!--Card fields-->
<$list variable=cur_pk filter="[!regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_pk>is[system]count[]multiply<cur_skipsystem_text>match[0]]">
<$list variable=cur_field filter="[<cur_pk>fields[]]">
<$list variable=found_field filter="[<cur_pk>get<cur_field>regexp<cur_search_text>]">

<$link to=<<cur_pk>> />: <<cur_field>>
<$list variable=disp_code filter="[<cur_showcode_text>match[yes]]">
<$codeblock code=<<found_field>> />
</$list><!--disp_code-->
</$list><!--found_field-->
</$list><!--cur_field-->

</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

</$list><!--cur_skipsystem_text-->
</$list><!--cur_showcode_text-->
</$list><!--cur_search_text-->
</$list><!--skip_system_pk-->
</$list><!--show_code_pk-->
</$vars><!--search_text_pk-->

TiddlyWiki\Section Display

Formatting Text TWCard

Card name = mcr glbl_section_disp

Tag = $:/tags/Macro

\define glbl_section_disp(ur_title, ur_section_num)
<$reveal type="nomatch" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="show">

!!$ur_title$ - Show
</$button></$reveal>
<$reveal type="match" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">

!!$ur_title$
</$button><br>

<<section$ur_section_num$>>

<$button style="float:right" class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">
---
</$button><br>
</$reveal>
\end
<!--|v
-- Card content call

\define section1()

section content

!!!here

\end
<<glbl_section_disp "Section 1" 1>>
^|-->

TiddlyWiki\Source Code Samples

CodeLibrary TWCard

TiddlyWiki Git repository sample code

[Home button] Tiddly Wiki Home Button source code

->

{{$:/core/images/home-button}}

[Save button] TiddlyWiki Save Button source code

->

<$action-sendmessage $message="tm-save-wiki" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>
  • This code says I can specify my own download file name
<span class="tc-dirty-indicator">
  • This code changes the color of elements within the <span> to red when the Wiki file has not been saved

[TiddlyWiki TopBar Menu]

TiddlyWiki TopBar Menu

->

<$button set="$:/state/sidebar" setTo="no"/>
<$button set="$:/state/sidebar" setTo="yes"/>
  • These lines show that the $:/state/sidebar Card is "no" to hide the sidebar, or "yes" show it

TiddlyWiki\Split Lines into Storage

AssignVariable Text TWCard
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>fields:exclude[created title modified]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<new_line_pk>> $field=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:25px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Temp Table

AssignVariable CodeLibrary TWCard
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>indexes[]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<ttbLINE>> $index=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:200px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$link to=<<ttbLINE>> />
<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Text Differences

Extract Text TWCard
<$diff-text source={{FirstTiddler}} dest={{SecondTiddler}}/>

TiddlyWiki\Textbox field

AssignVariable TWCard

You can choose to edit a Card or a Card's field in a single-line or multi-line textbox.

  • The default parameter is automatically placed in the textbox when the Card does not exist
    • Typing in the box will add to the default text
    • The Card will be created when the text in the box is changed
    • Otherwise the default text will not be saved
  • The placeholder parameter is shown as greyed-out text when the Card does not exist and there is no default text, or the Card exists and the text field is empty
    • Typing in the box will overwrite the placeholder text

Note: Editing a Card PK that starts with $:/state/popup/ will not be saved and does not affect the Wiki's "dirty" flag

$:/state/popup/TestText1

<$edit-text tiddler="$:/state/popup/TestText1" field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>


$:/state/popup/TestText2

<$edit-text tiddler="$:/state/popup/TestText2" field=text default="here" placeholder="[no text yet]" autoHeight=yes tag=textarea/>


TiddlyWiki\TiddlySaver from Downloads

FileSystem TWCard WindowsOS

Make a small form with a timer that moves downloaded TiddlyWiki files back to their original folder

- I have not tried to play around with running TW5 on Node.js. I don't prefer having to use TiddlyDesktop as a separate web browser. Installing a plugin would only save my wiki changes under the downloads directory. I like using a portable web browser on my thumb drive, and I am able to run non-admin programs on my computer. So I made a small program with a timer to move each saved TW file from my Downloads directory back to its original loading location.

- I leave the program running all the time I am logged in. Alt-S saves the data in TiddlyWiki to the Downloads folder. After at most five seconds, the timer moves the file to overwrite the original location. The form flashes on the screen for one second and then hides itself until another move.

1) I created an alt-S shortcut macro to save the current wiki with a specific filename prefix (TWMove_), the entire file path - with substitutions for path-specific characters (: and \), and a time stamp. (Using split/join is accurate enough for me.)

Example: TWMove_C-colon-slash-RootDirOne-slash-SubDirTwo-slash-UrWiki.html


\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.html]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>

2) I have my web browser save all downloaded files to a specific Downloads folder. (Specifically on Google Chrome, I did install a plugin to automatically hide the dowloaded files bar. It was getting annoying.)

3) I created a small program with a multi-line textbox, and a timer to poll the Downloads folder every five seconds. It moves all the TWMove files in alphabetical order, so the latest timestamped file will be processed last. It finds the destination path as part of the filename. (Moving assumes the original TW.html file is not locked by the browser. This happened to me once, but I just had to restart the browser to release the file lock.)

The program's text box shows the folder I'm polling. When it picks up a file, the original path is pre-pended to the textbox's list of processed files and the form flashes in the foreground for a second. (I could have made a system tray pop-up notification instead.)

It's not perfect, but definitely doable for most amateur programmers.


TiddlyWiki\Transclude Card Field

Extract Text TWCard
<$transclude mode="block" tiddler=<<currentTiddler>> />

<$transclude mode="inline" tiddler=<<currentTiddler>> field="ref_data" />

TiddlyWiki\Unicode Character List

CodeLibrary TWCard Unicode
\define CharRef(ur_code, ur_line_grouping)
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]floor[]] " variable=div_val>
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]match<div_val>] "><br><sub>$ur_code$
<<glbl_dec_to_hex5 "$ur_code$">>
</sub><br>
</$list>
</$list>
[&#$ur_code$;]
\end

https://en.wikipedia.org/wiki/Unicode_block

https://en.wikipedia.org/wiki/Plane_(Unicode)


<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text=""/>
Line Grouping = 10
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text="16"/>
Line Grouping = 16
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text=""/>
Clear selection
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="0"/>
Show Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="65536"/>
Show Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="131072"/>
Show Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="196608"/>
Show Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)
</$button>

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

@@font-family: "Lucida Console", Courier, monospace;
<$list filter="[{$:/state/mcr CharRef LineGrouping}!match[]else[10]] " variable=line_grouping>
<$list filter="[[$:/state/mcr CharRef CharacterListBase]get[text]!match[]]">
<$list filter="[range[512]subtract[1]multiply[128]add{$:/state/mcr CharRef CharacterListBase}]" variable=cur_block>
<h2><<cur_block>></h2>
<$list filter="[range[128]subtract[1]] +[add<cur_block>] " variable=cur_code>
<$macrocall $name=CharRef ur_code=<<cur_code>> ur_line_grouping=<<line_grouping>> />
</$list>
</$list>
</$list>
</$list>


TiddlyWiki\Unicode Codepoints Used

Extract TWCard Unicode
\define dec_to_u_hex4()
<$list variable=cur_d4 filter="[[$(dec_num)$]divide[16]floor[]divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d4 filter="[[0]subtract<cur_d4>multiply[16]multiply[16]multiply[16]add[$(dec_num)$]]"
><$list variable=cur_d3 filter="[<rem_d4>divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d3 filter="[[0]subtract<cur_d3>multiply[16]multiply[16]add<rem_d4>]"
><$list variable=cur_d2 filter="[<rem_d3>divide[16]floor[]]"
><$list variable=rem_d2 filter="[[0]subtract<cur_d2>multiply[16]add<rem_d3>]"
><$list variable=hex filter="[[;]addsuffix<cur_d4>addsuffix[;]addsuffix<cur_d3>addsuffix[;]addsuffix<cur_d2>addsuffix[;]addsuffix<rem_d2>split[;10]join[A]split[;11]join[B]split[;12]join[C]split[;13]join[D]split[;14]join[E]split[;15]join[F]split[;]join[]]"
>\u<<hex>></$list><!--hex
--></$list><!--rem_d2
--></$list><!--cur_d2
--></$list><!--rem_d3
--></$list><!--cur_d3
--></$list><!--rem_d3
--></$list><!--cur_d4
-->
\end
\define entry_hexcode(ur_char, ur_code_page)
<$list variable=cur_codepage filter="""[[$ur_code_page$]!match[]else[0]multiply[256]]""">
<$list variable=dec_num filter="""[range[256]add<cur_codepage>]""">
<$wikify name=hex_unicode text=<<dec_to_u_hex4>> >
<$list filter="""[[$ur_char$]regexp<hex_unicode>]""" variable=match_text>
-$ur_char$-<<hex_unicode>>-&amp;#<<dec_num>>;
</$list><!--match_text-->
</$wikify><!--hex_unicode-->
</$list><!--cur_unicode-->
</$list><!--cur_unicode-->
\end
\define unicode_points(ur_pk)
<$list variable=code_page filter="[[$:/state/unicode_points_codepage]get[text]else[0]]">

Code page = <<code_page>> <$button

style="margin-left:30px">
<$list variable="next_page" filter="[<code_page>add[1]]"><$action-setfield $tiddler="$:/state/unicode_points_codepage" text=<<next_page>>/></$list>
Next page
</$button><$button

style="margin-left:30px">
<$action-setfield $tiddler="$:/state/unicode_points_codepage" text="0"/>
Reset
</$button><br>


<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]count[]!match[1]!match[0]]">-&#x005D;-\u005D-&amp;#93;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u0060]count[]!match[1]!match[0]]">-&#x0060;-\u0060-&amp;#96;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]join[]splitregexp[\u0060]join[]split[]each:value[]sort[]]">-<<cur_char>>-
<$macrocall $name=entry_hexcode ur_code_page=<<code_page>> ur_char=<<cur_char>> />
<br>
<br>
</$list><!--cur_char-->
</$list><!--code_page-->
\end

<<unicode_points "UrPK">>

TiddlyWiki\Upload File

Extract FileSystem TWCard

Drag and drop

  • Drag a file icon from the Windows Desktop or Windows Explorer over the Wiki until you see a top-margin green bar show
  • Release the mouse to drop the file -> Opens card

Import Card

  • Review the file list and uncheck and undesired import objects
  • Click button Import -> Creates Cards

BrowseWidget

  • Create a $browse tag -> Makes button
  • Click button Choose File -> Opens dialog
  • Choose a file -> Closes dialog, opens Card

Import Card

  • Review the file list and uncheck and undesired import objects
  • Click button Import -> Creates Cards
<$browse />

TiddlyWiki\Video and Audio

Audio TWCard Video
  • Title = mcr glbl_ext_av
  • Tag = $:/tags/Macro
  • Note: The paths are relative to the current website. You cannot load Video or Audio content from other websites due to browser restrictions.
  • Note: You can add attribute poster="placeholder.png" to the Video tag if you have a specific image you want instead of the video's first frame
\define glbl_ext_video(UrFolder,UrVideo,UrTime)
<video width="320" height="180"
controls preload="metadata">
<source src="$UrFolder$/$UrVideo$.mp4#t=$UrTime$" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
\end
\define glbl_ext_audio(UrFolder,UrAudio,UrTime)
<audio controls preload="none">
<source src="$UrFolder$/$UrAudio$.mp3#t=$UrTime$" type=
"audio/mp3">
Your browser does not support the HTML 5 audio tag.
</audio>
\end

<!--|v
* Hard-coded to only use MP4 files

<<glbl_ext_video "MyVideosSubFolder" "MyVideoFile" "00:01:00">>

<<glbl_ext_video "file:///C:/UrFolder/UrSubFolder" "UrFilenameNoExtension" "00:01:00">>
^|-->
<!--|v
<<glbl_ext_audio "MyAudioSubFolder" "MyAudioFile" "00:01:00">>
^|-->

TiddlyWiki\View All Cards

CodeLibrary Extract TWCard
<$list filter="[all[tiddlers]!tag[EXTLINK]!tag[IMG]!tag[INDEX]!tag[MCR]!tag[META]!has[draft.of]!is[image]!is[tag]!is[system]has[tags]!prefix[undefined]sort[title]]">
<hr>
<h2><$link to=<<currentTiddler>> /></h2>
{{||$:/core/ui/ViewTemplate/tags}}
<$transclude mode="block"/>
</$list>

TiddlyWiki\Wikify Text

Extract Text TWCard
<$wikify name=str_text_out text="&#65;">
A = <<str_text_out>>
</$wikify>

<$wikify name=str_text_out text="''bold font''" output=html>
B = <<str_text_out>>
</$wikify>

TiddlyWiki\WikiText Formatting

CodeLibrary Formatting Text TWCard

You can type most standard text without problems. Leading, repeated, or paired special characters may need escaped.

Vertical Spacing

Pressing enter at the end of a line does not start a new paragraph.
Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph.
Press enter twice.

For example, see how the above two paragraphs are shown below:

Pressing enter at the end of a line does not start a new paragraph. Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph. Press enter twice.

Leading Special Characters

Bulleted List Entry

*Bulleted List Entry
  • Bulleted List Entry

Leading with an asterisk creates a bulleted list entry. To escape, prefix with four single-quotes.

If you want a single blank line between two bullet points, use a !! Heading Line without any title text.

''''*Bulleted List Entry

*Bulleted List Entry

Heading Line

!Heading Line

Starting a new paragraph line with an exclamation mark (!) results in a heading line.

!Heading Line

The above heading markup starts with an exclamation mark. To escape, prefix with four single-quotes.

''''!Heading Line

!Heading Line

Mono-spaced Text Block

 ```
 Mono-spaced Text Block
 ```
Mono-spaced Text Block

Leading with a triple back-tick creates a mono-space text block. To escape, surround the triple back-tick with doubled square-brackets.

[[''']] Regular typeface

``` Regular typeface

Numbered List Entry

#Numbered List Entry
  1. Numbered List Entry

Leading with a pound-sign creates a numbered list entry. To escape, prefix with four single-quotes.

''''#Numbered List Entry

#Numbered List Entry

Quoted text block

<<<
Quoted text block
<<<

Quoted text block

Leading with a triple less-than creates a quoted text block. To escape, surround the

''''<<< Unquoted text

<<< Unquoted text

URL Links

https://tiddlywiki.com/

https://tiddlywiki.com/

Start text with an "http://" "http://" will create a URL link. To escape, place four single-quotes before the colon and between the double forward-slashes.

https'''':/''''/tiddlywiki.com/

https://tiddlywiki.com/

Repeated Special Characters

''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`

Bold Text Italic Text Strike-through Text Underlined Text Raised-Small Text Lowered-Small Text Mono-spaced Text

A number of repeated special characters are used as Wiki Markup to format text. To escape, place four single-quotes between the doubled characters or surround the doubled characters with doubled square-braces.

[['']]Bold Text[['']] /''''/Italic Text/''''/ ~''''~Strike-through Text~''''~ _''''_Underlined Text_''''_ ^''''^Raised-Small Text^''''^ ,'''',Lowered-Small Text,'''', [[`]]Mono-spaced Text[[`]]

''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`

Paired Special Characters

Literal Text

[[Literal Text]]

Literal Text

Surrounding text with doubled square-brackets shows the literal surrounded text without applying formatting. To escape, place four single-quotes between the first doubled square-brackets.

[''''[Literal Text]]

[[Literal Text]]

Transcluded Text

{{Other Tiddler Title}}

Note: The other tidder's content is "Other Tiddler Transcluded Text".

Surrounding text with doubled curly-braces shows the full content of another tiddler. To escape, place four single-quotes between the first doubled curly-braces.

{''''{Other Tiddler Title}}

{{Other Tiddler Title}}

HTML Markup

<b>HTML Markup</b>

HTML Markup

Surrounding text with angled-brackets uses HTML formatting. To escape, rename the first angle-bracket to &lt;

&lt;b>HTML Markup</b>

<b>HTML Markup</b>

HTML Literals

&lt;

Note: &lt; represents a left angle-bracket, or the less-than symbol (<).

<

Surrounding text with an ampersand (&) and a semi-colon translate to an HTML literal. To escape, place four single-quotes after the ampersand.

&lt;

&lt;

CSS Styles

You can apply CSS styles in-line with the text. Make sure you put the semi-colon at the end of the style list.

You can apply @@background-color:yellow; CSS styles @@ in-line with the text.

You can apply CSS styles in-line with the text.

Tables

|!Cell1 |!Cell2 |
|Cell3 |Cell3 |

|^top left |^ top center |^ top right|
|middle left | middle center | middle right|
|,bottom left |, bottom center |, bottom right|


To merge a table cell with the one above, use the special cell text ~. To merge a cell with the one to its left use the text <. To merge one to its right use >. For example:

|Cell1 |Cell2 |Cell3 |Cell4 |
|Cell5 |Cell6 |Cell7 |<|
|Cell5 |~|Cell7 |Cell8 |
|>|Cell9 |Cell10 |Cell11 |

assigns the CSS classes "myclass" and "anotherClass" to the table
gives the table the caption "This is a caption"
adds a header row of cells with the text "Header"
adds a footer row of cells with the text "Footer"
|myclass anotherClass|k
|This is a caption |c
|Cell1 |Cell2 |
|Cell3 |Cell3 |
|Header|Header|h
|Footer|Footer|f

TiddlyWiki\Word Wrap

Text TWCard WordWrap

Hard-line breaks using CSS styles

.tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
  • Note: When using this alternate CSS, wiki text markup will be ignored unless preceded by a double-spaced line
  • Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

Sample Code:

*bullet 1
*bullet 2
*bullet 3
Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a ",,,,",,,," wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

*bullet 4 requires a preceding double-spaced line to be interpreted as wikitext

Results:

* bullet 1
* bullet 2
* bullet 3

Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a """ wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

* bullet 4 requires a preceding double-spaced line to be interpreted as wikitext

Apply stylesheet to cards with specific tag linewrap

[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}

Apply Styles to In-line Text

  • Start a text block with @@ and the CSS styles with no spaces

Sample Code:

@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line

Result:

These are
separate lines
here

This is one big line
  • or start in the middle of a text block

Sample Code:

This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.

Result:

This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.

TotalCommander

DOC

  1. Create new Text File
  2. Local file desktop shortcut


TotalCommander\Create new Text File

AndroidOS FileSystem Text

[Total Commander directory]
- [Top of the directory]
- Hold down on the '..' button to see the menu -> Opens menu
- - or Hold down on any subdirectory name to see the menu -> Opens menu

- [context menu]
- Click option New Text file -> Opens dialog

- [Create new text file dialog]
- Enter a new text file name
- Click button OK -> Closes dialog

- [Directory list]
- Note: The new file was added to the current folder


TotalCommander\Local file desktop shortcut

AndroidOS AssignVariable FileSystem

Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Total Commander directory]
- Hold down on file entry named like *.html -> Opens menu

- [context menu]
- Click option Create link on desktop -> Opens dialog

- [Create link dialog, main page, command line section]
- Click button '>>' -> Opens dialog

- [Choose app dialog, main page]
- Click option Choose app * -> Navigates page

- [Choose app dialog, Choose app * page]
- Click option Chrome -> Navigates page

- [Create link dialog, main page]
- Click button OK / Apply -> Closes dialog

[Android Desktop icons]
- Note: The icon was added to the desktop automatically


TW Project

DOC

  1. Check app
  2. Code Snapshot
  3. Features list
  4. Javascript Plugin instructions
  5. Shuffle List addon
  6. Text Replace addon
  7. TiddlyWiki Manual
  8. TW JS Pretty
  9. Wiki Empty Setup


TW Project\Check app

CodeLibrary TWCard

Project Check app

->

Goal: Find food by aisle


TW Project\Code Snapshot

CodeLibrary TWCard

TW Snapshot Review

->

Goal: Browse the code inside the WIki file

TW Snapshot v5d01d23 main-site

->

TW Snapshot v5d01d23 empty

->

TW Snapshot v5d01d23 pre-release

->

TW Snapshot v5d01d23 update

->


TW Project\Features list

CodeLibrary TWCard

TW Features

->

Goal: Demonstrate every Wiki command and option


TW Project\Javascript Plugin instructions

JavaScriptCode TWCard

TW Create Javascript Plugin

->


TW Project\Shuffle List addon

CodeLibrary Filter TWCard

Shuffle List Entries

->


TW Project\Text Replace addon

AssignVariable Text TWCard

TW Addon Text Replace

->

Goal: Add text replacement functionality to the standard TWCard editor


TW Project\TiddlyWiki Manual

CodeLibrary TWCard

TW Manual

->

Goal: Explain the Single-Page Quine Wiki architecture


TW Project\TW JS Pretty

Formatting JavaScriptCode TWCard

TW JS Pretty

->

Goal: Upload a text file and comment on each line, table or function


TW Project\Wiki Empty Setup

Extract HTMLCode TWCard

Empty Wiki Setup

->

Goal: Use the empty TW document and generate a static HTML page


Unicode\Code Blocks

CodeLibrary Text Unicode

Unicode Block 00-Basic Latin

->

Unicode Block 01-Latin Supplement

->

Unicode Code Block List

->

Unicode Block Planes

->

Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)

Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)

Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)

Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.


Unicode\Latest Version

CodeLibrary Text Unicode

Unicode Character Database

->

All files for the most up-to-date version of the Unicode Character Database can be found at: http://www.unicode.org/Public/UCD/latest/.

The latest text file databases are at https://www.unicode.org/Public/UCD/latest/ucd/. The latest set of text file databases is in a ZIP file at https://www.unicode.org/Public/UCD/latest/ucd/UCD.zip.

The list of Unicode Code Blocks are in the text database https://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt.

There is a list of names for the Unicode Code Points at https://www.unicode.org/Public/UCD/latest/ucd/Index.txt. There same list is sorted in Code Point order at https://www.unicode.org/Public/UCD/latest/ucd/NameAliases.txt. Each hex code can have multiple names.

The unique list of Unicode Code Points is at https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt. There is a character name and possibly an alternative name on each row.


VBNetCode

DOC

  1. Application Startup require DLLs
  2. Checksum calculate
  3. Copy File Lines
  4. DotNet Core Compile EXE
  5. DotNet Core Installation using Binaries
  6. DotNet Core Installed Path
  7. DotNet Core New Project
  8. DotNetCore Installation using Installer
  9. File Exists
  10. File Size
  11. Global functions passed as Classes
  12. In-Memory Compile
  13. Send Keys
  14. Text file to JSON Lines
  15. To Hex
  16. Unicode Code Point
  17. UserBowl example
  18. Version


VBNetCode\Application Startup require DLLs

CodeLibrary VBCode
Option Strict On
Namespace My
    Partial Friend Class MyApplication
        Sub Main(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
            Mx.Want.TestReferencedAssemblies_errhnd(e)
            'Next goes to frmInput_1_Load, then Want.Compile_And_Run_Script
        End Sub
    End Class
End Namespace

Namespace Mx
    Partial Public Class Want
        Public Shared Sub TestReferencedAssemblies_errhnd(ur_startup_event_args As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs)
            Dim objERR_LIST = New ErrListBase : Try
                Call Assistant.TestReferencedAssemblies()

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                MsgBox(objERR_LIST.ToString, , My.Application.Info.Title)
                ur_startup_event_args.Cancel = True
            End If
        End Sub 'TestReferencedAssemblies_errhnd
    End Class 'Want
    
    Partial Public Class Assistant
        Public Shared Sub TestReferencedAssemblies()
            'Will error if DLL does is not available
            Dim objV1 = System.Data.SqlClient.SortOrder.Ascending
        End Sub 'TestReferencedAssemblies
    End Class 'Assistant
End Namespace 'Mx

VBNetCode\Checksum calculate

Extract Numbers VBCode

I want a .Net program to calculate the SHA512 hash of a file

Dim strHASH_KEY = ""
Using objSHA = New System.Security.Cryptography.SHA512Managed
    Using stmFILE = System.IO.File.OpenRead(flnDATA)
        strHASH_KEY = "[" & System.BitConverter.ToString(objSHA.ComputeHash(stmFILE)).Replace("-", "").ToLower & "]"
        'Convert.ToBase64String(
    End Using
End Using

VBNetCode\Copy File Lines

Extract FileSystem VBCode
Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), bolAPPEND_FILE, gUTF8_FileEncoding)
	Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
		While stmDATA.EndOfStream = False
			'Character copy
			Dim intENTRY = stmDATA.Read()
			Dim strENTRY = ChrW(intENTRY)
			stmOUT_FILE.Write(strENTRY)
			
			'Line copy
			Dim strLINE = stmDATA.ReadLine()
			stmOUT_FILE.WriteLine(strLINE)
		End While 'stmDATA
	End Using 'stmDATA
End Using 'stmOUT_FILE

Split File into chunks of 100,000 lines each

Dim intFILE_COUNT = 0
Dim intLINE_COUNT = 0
Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
	While stmDATA.EndOfStream = False
		intFILE_COUNT += 1
		intLINE_COUNT = 0
		Dim strFILE_COUNT = intFILE_COUNT.ToString()
		If Len(strFILE_COUNT) = 2 Then
			strFILE_COUNT = "c" & strFILE_COUNT
		ElseIf Len(strFILE_COUNT) = 3 Then
			strFILE_COUNT = "d" & strFILE_COUNT
			
			End If 'strFILE_COUNT
		
		strFILE_COUNT = "e" & strFILE_COUNT
		Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT(strFILE_COUNT & ".TXT"), False, gUTF8_FileEncoding)
			While stmDATA.EndOfStream = False
				Dim strLINE = stmDATA.ReadLine()
				stmOUT_FILE.WriteLine(strLINE)
				intLINE_COUNT += 1
				
				If intLINE_COUNT >= 100000 Then
					Exit While
					
					End If
				
				End While 'stmDATA
			
			End Using 'stmOUT_FILE

		End While 'stmDATA
	
	End Using 'stmDATA

VBNetCode\DotNet Core Compile EXE

Extract VBCode WindowsOS

[https://github.com/dotnet/core/issues/5409]

In .NET 5 the single-file publish may produce more than one file and it's by design. See the expected behavior described here:

https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md#user-experience

In 3.1 single-file is basically just a self-extracting executable - it writes everything into temp and runs from there. As such for the running app nothing really changes (everything is a file, with a path and so on).

In 5 we don't write to disk by default, all managed assemblies are loaded directly from the executable. The problem is native libraries - it's technically VERY difficult to include a random .dll in an executable and run it from the executable directly.

If you only take the .exe and run it, it won't work - it needs those additional files.

If you need .NET 5 but want the self-extracting behavior you can set IncludeAllContentForSelfExtract=true and it will behave basically the same as in 3.1.

There's also a "hybrid" mode IncludeNativeLibrariesForSelfExtract=true which will produce just one executable and that will write the native libraries to temp and then run.

User-replaced value = UrProjectDir

[UrProjectDir folder] - Start with VBNetCode\DotNet Core New Project

[Windows CLI]
- [Compile into an EXE]
- dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep
- Text output ->

Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  t3 -> UrProjectDir\bin\Release\net5.0\win10-x64\UrProjectDir.dll
  t3 -> UrProjectDir\Dep\

[UrProjectDir folder]
- [Look for the new folders]
- New sub-folders: bin, Dep
- Note: The compiled program is in the Dep subfolder named UrProjectDir.exe
- - The UrProjectDir.pdb file is used for debugging purposes and would not normally be deployed with your EXE file

[Windows CLI]
- [Remove the temporary folders in the UrProjectDir]
- rd bin /s /q
- rd obj /s /q
- [Run the project]
- Dep\UrProjectDir.exe
- Text output shows as if you ran the command dotnet run

- Note: You can output the System.AppContext.BaseDirectory to find the Temp that holds the uncompressed program

[Program.vb file]
- [Replaces lines in Main sub]
- Console.WriteLine(System.AppContext.BaseDirectory)

[Windows CLI]
- [Compile into an EXE]
- dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep
- Note: If running DotNet Core 3.1,
- - dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true -p:PublishSingleFile=true
- - The "–self-contained" option is incompatible with the "-p:PublishReadyToRun=true" and "-p:PublishSingleFile=true" options

- Note: When you choose the Portable publish option, you'll get a package that is capable of running on either x86 (32-bit) machines and x64 (64-bit) machines
- - The next run would have to JIT compile the application again as it is used
- - The advantage here is that you'd only need to distribute one package, and it'll run on both x86/x64 machines
- - dotnet publish -c Release -r portable --self-contained

- [Remove the temporary folders in the UrProjectDir]
- rd bin /s /q
- rd obj /s /q
- [Run the project]
- Dep\UrProjectDir.exe
- Text output =

C:\Users\UrUsername\AppData\Local\Temp\.net\UrProjectDir\SomeRandom-8-letters.SomeRandom-3-letters\

- Note: This folder gets created on the first run the of UrProjectDir.exe
- - The second run starts faster because the files have already been extracted to this temporary folder
- - You can delete the temporary folder, and running the UrProjectDir.exe will create it again.

- Note: You can specify a different temporary folder by setting the Environment Variable DOTNET_BUNDLE_EXTRACT_BASE_DIR

- SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%USERPROFILE%\Downloads\UrProjectDir\tmp
- Note: You can set the Environment Variable in a batch file and it will not be saved for new Windows CLI windows.
- - To set it permanently, use Control Panel \ System and Security \ System \ Advanced systems settings \ Advanced tab \ Environment Variables button \ top or bottom section \ New button, Variable Name = DOTNET_BUNDLE_EXTRACT_BASE_DIR, Variable Value = UrFullPathToTempDirectory, OK button
- - Trying to use a relative directory path ends up not running the executable

- [Run the project]
- Dep\UrProjectDir.exe
- Text output =

C:\Users\UrUsername\Downloads\UrProjectFolder\tmp\UrProjectFolder\SomeRandom-8-letters.SomeRandom-3-letters\

- [Review the size of the TMP folder]
- dir tmp /s
- Text output = 23 Files, 8 Dirs

- [Remove the temporary directory]
- rd tmp /s /q

[UrProjectDir\Dep folder]
- [Create a script to run the project and clean up the temporary files]
- New file = UrProjectDir.cmd

[UrProjectDir.cmd file]

@@ECHO OFF
SET CUR_DIR=%~dp0
SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%CUR_DIR%tmp
"%CUR_DIR%UrProjectDir.exe"
rd "%CUR_DIR%bin" /s /q 2> nul
rd "%CUR_DIR%obj" /s /q 2> nul
rd "%CUR_DIR%tmp" /s /q 2> nul

[Windows CLI]
- [Run the clean-execution script]
- Dep\UrProjectDir.cmd
- Note: There is no tmp subfolder


VBNetCode\DotNet Core Installation using Binaries

VBCode WindowsOS

[https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net50]

As an alternative to the Windows installers for .NET, you can download and manually install the SDK or runtime. Manual install is usually performed as part of continuous integration testing. For a developer or user, it's generally better to use an installer.

Both .NET SDK and .NET Runtime can be manually installed after they've been downloaded. If you install .NET SDK, you don't need to install the corresponding runtime. First, download a binary release for either the SDK or the runtime from one of the following sites:

https://dotnet.microsoft.com/download/dotnet/5.0

https://dotnet.microsoft.com/download/dotnet-core

Create a directory to extract .NET to, for example %USERPROFILE%\dotnet. Then, extract the downloaded zip file into that directory.

By default, .NET CLI commands and apps won't use .NET installed in this way and you must explicitly choose to use it. To do so, change the environment variables with which an application is started:

set DOTNET_ROOT=%USERPROFILE%\dotnet
set PATH=%USERPROFILE%\dotnet;%PATH%
set DOTNET_MULTILEVEL_LOOKUP=0

This approach lets you install multiple versions into separate locations, then explicitly choose which install location an application should use by running the application with environment variables pointing at that location.

When DOTNET_MULTILEVEL_LOOKUP is set to 0, .NET ignores any globally installed .NET version. Remove that environment setting to let .NET consider the default global install location when selecting the best framework for running the application. The default is typically C:\Program Files\dotnet, which is where the installers install .NET.

[https://docs.microsoft.com/en-us/dotnet/core/install/how-to-detect-installed-versions?pivots=os-windows]

When you install .NET from an installer or script, it's installed to a standard folder. Much of the time the installer or script you're using to install .NET gives you an option to install to a different folder. If you choose to install to a different folder, adjust the start of the folder path.

dotnet executable in C:\program files\dotnet\dotnet.exe

.NET SDK in C:\program files\dotnet\sdk\{version}\

.NET Runtime in C:\program files\dotnet\shared\{runtime-type}\{version}\


VBNetCode\DotNet Core Installed Path

Extract FileSystem VBCode

[Windows CLI]
- [Run the system information report]
- dotnet --info

.NET Core SDK (reflecting any global.json):
 Version:   3.1.401
 Commit:    5b6f5e5005

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18363
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.401\

Host (useful for support):
  Version: 3.1.7
  Commit:  fcfdef8d6b

.NET Core SDKs installed:
  3.1.301 [C:\Program Files\dotnet\sdk]
  3.1.401 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download

VBNetCode\DotNet Core New Project

Extract VBCode

[https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new]

You can run dotnet new –list or dotnet new -l to see a list of all installed templates. If the TEMPLATE value isn't an exact match on text in the Templates or Short Name column from the returned table, a substring match is performed on those two columns.

Starting with .NET Core 3.0 SDK, the CLI searches for templates in NuGet.org when you invoke the dotnet new command in the following conditions:

  • If the CLI can't find a template match when invoking dotnet new, not even partial.
  • If there's a newer version of the template available. In this case, the project or artifact is created but the CLI warns you about an updated version of the template.

[https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli]

User-replaced value = UrProjectDir

[Windows CLI]
- [Navigate to the User Downloads folder]
- cd %USERPROFILE%\Downloads
- [Create a new DotNet Core project named UrProjectDir]
- dotnet new console -lang VB -o UrProjectDir
- Text output =

Getting ready...
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj...
  Determining projects to restore...
  Restored C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj (in 65 ms).
Restore succeeded.

- [Navigate to the new UrProjectDir]
- cd UrProjectDir

[UrProjectDir folder]
- [Look for the new files and folders]
- New files: UrProjectDir.vbproj and Program.vb
- New sub-folder: obj

[Windows CLI]
- [Download a dependency]
- dotnet add package Figgle
- Text output =

  Determining projects to restore...
  Writing C:\Users\Dad\AppData\Local\Temp\tmpE018.tmp
info : Adding PackageReference for package 'Figgle' into project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info :   GET https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json
info :   OK https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json 104ms
info : Restoring packages for C:\Users\Dad\Downloads\t3\t3.vbproj...

info : Installing runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple 4.3.0.
info : Installing runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl 4.3.0.

info : Package 'Figgle' is compatible with all the specified frameworks in project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : PackageReference for package 'Figgle' version '0.4.0' added to file 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : Committing restore...
info : Writing assets file to disk. Path: C:\Users\Dad\Downloads\t3\obj\project.assets.json
log  : Restored C:\Users\Dad\Downloads\t3\t3.vbproj (in 8.04 sec).

[Program.vb file]
- [Replace lines in Main sub]
- Console.WriteLine(Figgle.FiggleFonts.Standard.Render("Hello, World!"))

[Windows CLI]
- [Compile into an EXE and run it]
- dotnet run
- If you did not enter the program line incorrectly, Text output =

Program.vb(5,79): error BC30037: Character is not valid.

The build failed. Fix the build errors and run again.

- If you entered the program line correctly, Text output shows Hello World in a large font


VBNetCode\DotNetCore Installation using Installer

VBCode WindowsOS

[https://dotnet.microsoft.com/platform/support/policy/dotnet-core]
- 2020m11d24: .NET 5 is the current version of DotNet Core. It was released on November 10, 2020.

[https://dotnet.microsoft.com/download/dotnet-core]
- [Supported versions, record Version = .NET 5.0]
- Click link .NET 5.0 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/5.0]
- [record Release Information = v5.0.0, Build Apps column]
- [SDK grid, record OS = Windows]
- Click link x86 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-windows-x64-installer]
- Auto-download started -> Saves file

[Local Computer Downloads folder]
- [filename = dotnet-sdk-5.0.100-win-x64.exe]
- Run program -> Opens form

[Microsoft .NET SDK 5.0.100 (x64) Installer window]
- Click button Install -> Windows dialog
- Question: Do you want to allow the program to make changes to your computer?
- Click button Yes -> Closes dialog
- Wait for progress bar to complete -> Navigates page
- Note: Installation was successful
- Click button Close -> Closes window

VBNetCode\DotNet Core Installed Path


VBNetCode\File Exists

Extract FileSystem VBCode
Dim bolFILE_EXISTS = System.IO.File.Exists(flnDATA)

VBNetCode\File Size

Extract FileSystem VBCode
Dim sioFILE = New System.IO.FileInfo(flnDATA)
Dim intFILE_SIZE = sioFILE.Length

VBNetCode\Global functions passed as Classes

AssignVariable CodeLibrary VBCode
    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

VBNetCode\In-Memory Compile

CodeLibrary Extract VBCode
Namespace Mx
    Public Class ScriptRun
        ' Build a Hello World program graph using 
        ' System.CodeDom types.
        Public Class enmC_V_J
            Inherits bitBASE
            Public Shared CSharp As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared VisualBasic As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared JScript As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
        End Class 'enmC_V_J

        Public Shared Function RunCode(ur_provider As Mx.ScriptRun.enmC_V_J, ur_input_script As String, ur_assembly_folder As String) As String
            Dim strSOURCE_CODE = ur_input_script
            Dim stpERR_MSG = Strapd()
            Dim stpCODE_FILE = Strapd()
            ' Configure a CompilerParameters that links System.dll and produces the specified executable file.
            Dim objAPP_DOMAIN As AppDomain = Nothing
            Dim objCOMPILE_RUNNER As CompilerRunner = Nothing
            Dim objCOMPILER_PARM = New System.CodeDom.Compiler.CompilerParameters
            Dim objCOPMILER_RESULT As System.CodeDom.Compiler.CompilerResults = Nothing
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing

            If stpERR_MSG.Length = 0 Then
                'objAPP_DOMAIN = System.AppDomain.CreateDomain("MyDomain", AppDomain.CurrentDomain.Evidence, CreateSetup())
                'objCOMPILE_RUNNER = objAPP_DOMAIN.CreateInstanceFromAndUnwrap(GetType(CompilerRunner).Assembly.Location, GetType(CompilerRunner).FullName)
                objCOMPILE_RUNNER = New Mx.CompilerRunner
                stpERR_MSG.d(objCOMPILE_RUNNER.Compile(stpCODE_FILE.ToString, ur_provider.name, objCOMPILER_PARM))
            End If

            If stpERR_MSG.Length = 0 Then
                stpERR_MSG.d(objCOMPILE_RUNNER.Run("Mx.Class1", "RetVal"))
            End If

            If objAPP_DOMAIN IsNot Nothing Then
                'AppDomain.Unload(objAPP_DOMAIN)
            End If
            ' Return the results of compilation.
            Return stpERR_MSG.ToString
        End Function 'RunCode

        Public Shared Function CreateSetup() As AppDomainSetup
            Dim retSETUP = New AppDomainSetup
            With retSETUP
                .ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
                .ApplicationName = "TestDLL"
                .DisallowBindingRedirects = False
                .ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
                .LoaderOptimization = LoaderOptimization.MultiDomainHost
            End With
            CreateSetup = retSETUP
        End Function 'CreateSetup
    End Class 'ScriptRun

    Public Class CompilerRunner
        Inherits MarshalByRefObject

        Public cur_assembly As System.Reflection.Assembly = Nothing
        'AppDomain.CurrentDomain.FriendlyName = MyDomain

        Public Function Compile(ur_code As String, ur_provider As String, ur_compiler_parm As System.CodeDom.Compiler.CompilerParameters) As String
            Dim stpERR_MSG = Strapd()
            Me.cur_assembly = Nothing
            Dim provider As System.CodeDom.Compiler.CodeDomProvider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider(ur_provider) 'New Microsoft.VisualBasic.VBCodeProvider 
            Dim objCOMPILER_RESULT = provider.CompileAssemblyFromSource(ur_compiler_parm, ur_code) ' Strapd().d("Namespace Mx").dLine("Public Class Class1").dLine("Public Shared Function RetVal() As String").dLine("RetVal=""Hi""").dLine("End Function").dLine("End Class").dLine("End Namespace"))
            If objCOMPILER_RESULT.Errors.Count = 0 Then
                Me.cur_assembly = objCOMPILER_RESULT.CompiledAssembly

            Else
                stpERR_MSG.dLine("Compile Errors")
                stpERR_MSG.dLine()
                For Each errItem As System.CodeDom.Compiler.CompilerError In objCOMPILER_RESULT.Errors
                    stpERR_MSG.dLine(errItem.ErrorText & " [" & errItem.Line + 5 & "]")
                    stpERR_MSG.dLine()
                    stpERR_MSG.dLine()
                Next errItem

                stpERR_MSG.dLine(ur_code)
            End If 'objCOMPILER_RESULT

            Compile = stpERR_MSG.ToString
        End Function 'Comiple

        Public Function Run(ur_type_name As String, ur_method_name As String) As String
            Dim stpERR_MSG = Strapd()
            Dim t As System.Type = Me.cur_assembly.CreateInstance(ur_type_name).GetType()
            'Dim objRESULT = t.InvokeMember(ur_method_name, System.Reflection.BindingFlags.InvokeMethod, Nothing, Me.cur_assembly, {})
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing
            For Each m As System.Reflection.MethodInfo In t.GetMethods
                If m.Name = ur_method_name Then
                    objMETHOD_MAIN = m
                    Exit For
                End If
            Next m

            If objMETHOD_MAIN IsNot Nothing Then
                Dim objRESULT = objMETHOD_MAIN.Invoke(Nothing, Nothing)
                If objRESULT IsNot Nothing Then
                    stpERR_MSG.dLine(objRESULT.ToString)
                End If 'objRESULT
            End If 'objMETHOD_MAIN

            Run = stpERR_MSG.ToString
        End Function 'Run
    End Class 'CompileRunner
End Namespace 'Mx

VBNetCode\Send Keys

AssignVariable VBCode

Send one alt-tab

System.Windows.Forms.SendKeys.Send("%{TAB}")

Hold down Alt, press alt-tab twice, and release Alt

System.Windows.Forms.SendKeys.Send("%({TAB}{TAB})")

The Windows key is not so easy to emulate. - Auto-It or Auto-Hotkey can do more complicated patterns - VB.Net can use PInvoke to have more capabilities


VBNetCode\Text file to JSON Lines

Extract TWCard VBCode

This outputs a file that can be dragged into TiddlyWiki.

<$list variable=cur_char filter="[[UrPK]get[text]splitregexp[\n]join[]split[]each:value[]!match[ ]sort[]]">
<<cur_char>>:
<$list variable=disp_name filter="[[Unicode Char Names]getindex<cur_char>else[missing]]">
<<disp_name>>
</$list><!--disp_name-->
<br>
</$list><!--cur_char-->

[[Unicode Char Names]]
Dim strFILE_PATH = "UnicodeData.txt"
Dim strOUT_PATH = strFILE_PATH & ".json"
Using stmOUT_FILE = New System.IO.StreamWriter(strOUT_PATH)
	Dim qs = """"
	Dim strESC_DQT = "\" & qs
	stmOUT_FILE.Write("[{""created"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & ",""modified"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & "," &
		qs & "title" & qs & ":" & qs & "Unicode Char Names" & qs & ",""type"":""application/json"",""text"":""{")
	Using stmDATA = New System.IO.StreamReader(strFILE_PATH)
		Dim LINCTR = 0
		While stmDATA.EndOfStream = False
			Dim strLINE = stmDATA.ReadLine()
			Dim intFOUND_SPRTR = InStr(strLINE, ";")
			
			Dim strHEX = Mid(strLINE, 1, intFOUND_SPRTR - 1)
			Dim intCHAR = Cint("&H" & strHEX)
			Dim strCHAR = UCase(strHEX)
			Dim strPREFIX = Left(strCHAR, 2)
			If Len(strCHAR) <> 4 Then
				strPREFIX = ""
			End If
			
			If intCHAR < 32 Then
			  strCHAR = ""
			ElseIf intCHAR > 65534 OrElse
			  strPREFIX = "D8" OrElse
			  strPREFIX = "D9" OrElse
			  strPREFIX = "DA" OrElse
			  strPREFIX = "DB" OrElse
			  strPREFIX = "DC" OrElse
			  strPREFIX = "DD" OrElse
			  strPREFIX = "DE" OrElse
			  strPREFIX = "DF" Then
				strCHAR = "\u" & strHEX
			Else
				strCHAR = CHRW(intCHAR)
				If strCHAR = "\" Then
					strCHAR = "\\\\"
				ElseIf strCHAR = """" Then
					strCHAR = "\\\" & """"
				End If
			End If

			If strCHAR <> "" Then
				LINCTR += 1
				If LINCTR > 1 Then
					stmOUT_FILE.Write(",")
				End If
				stmOUT_FILE.Write("\n    " & strESC_DQT & strCHAR & strESC_DQT & ":" & " " & strESC_DQT & strLINE.Replace("\", "\\").Replace(Chr(10), "\n").Replace(qs, strESC_DQT).Replace("<", "&lt;") & strESC_DQT)
			End If
		End While 'stmDATA
	End Using 'stmDATA
	
	stmOUT_FILE.Write("\n}" & qs & "}]")
End Using 'stmOUT_FILE

VBNetCode\To Hex

Extract Numbers VBCode

Change string with numbers (0 to 9) and/or letters (a-f) into decimal number

[q/a page]
- https://stackoverflow.com/questions/642417/how-do-you-convert-hex-to-decimal-using-vb-net

[sample code]

Dim strTEXT = "FF"
Dim strHEX_CODE = "&H" & strTEXT
Dim intNUMBER = CInt(strHEX_CODE)
MsgBox(intNUMBER) -> 255

VBNetCode\UserBowl example

CodeLibrary Extract VBCode
    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As zapp_folder = TRow(Of enmUN).glbl.Trbase(Of zapp_folder).NewBitBase() : Public Class zapp_folder : Inherits enmUN : End Class
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared background_color As zbackground_color = TRow(Of enmUN).glbl.Trbase(Of zbackground_color).NewBitBase() : Public Class zbackground_color : Inherits enmUN : End Class
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_project_code As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared compiler_exe As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared form_title As zform_title = TRow(Of enmUN).glbl.Trbase(Of zform_title).NewBitBase() : Public Class zform_title : Inherits enmUN : End Class
        Public Shared path As zpath = TRow(Of enmUN).glbl.Trbase(Of zpath).NewBitBase() : Public Class zpath : Inherits enmUN : End Class
        Public Shared script_path As zscript_path = TRow(Of enmUN).glbl.Trbase(Of zscript_path).NewBitBase() : Public Class zscript_path : Inherits enmUN : End Class
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared window_status As zwindow_status = TRow(Of enmUN).glbl.Trbase(Of zwindow_status).NewBitBase() : Public Class zwindow_status : Inherits enmUN : End Class
    End Class

    Public Class enmUR_Color
        Inherits bitBASE
        Public Shared Clear As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Green As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Red As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
    End Class

    Public Class enmUR_Status
        Inherits bitBASE
        Public Shared Show As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
        Public Shared Close As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'db.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit(Have.WindowsMsgBox, Have.WindowsCboard)
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)
            Private enrBackground_Color As System.Drawing.Color
            Private enrUR_Color As enmUR_Color

            Public ReadOnly Property Background_Color_of_Form As System.Drawing.Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color_of_Form = Me.enrBackground_Color
                End Get
            End Property 'Background_Color_of_Form

            Public Property Background_Color As enmUR_Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color = Me.enrUR_Color
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As enmUR_Color)
                    Dim intCOLOR = System.Drawing.Color.Transparent
                    If value Is enmUR_Color.Red Then
                        intCOLOR = System.Drawing.Color.Red

                    ElseIf value Is enmUR_Color.Green Then
                        intCOLOR = System.Drawing.Color.Green
                    End If

                    Me.enrBackground_Color = intCOLOR
                    Me.enrUR_Color = value
                    Me.v(enmUB.contents) = value.name
                End Set
            End Property 'Contents

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_bowlname_is(ur_cmp As enmUN) As Boolean
                v_bowlname_is = AreEqual(Me.v(enmUB.bowl_name), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_cmp As enmUR_Color) As Boolean
                v_is = AreEqual(Me.Contents, ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit(ur_windowsmsgbox_env As Have.glblWindowsMsgBox, ur_windowscboard_env As Have.glblWindowsCboard)
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = ur_windowsmsgbox_env.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        ur_windowscboard_env.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Dim strASSEMBLY_EXE = mt
                Try
                    strASSEMBLY_EXE = My.Application.Info.Title
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_FOLDER = FileNamed()
                Try
                    flnASSEMBLY_FOLDER.wAssemblyDir(My.Application.Info)
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_PATH = flnASSEMBLY_FOLDER.gCopy.d(strASSEMBLY_EXE)
                Me.SelKey(enmUN.app_name).Contents = flnASSEMBLY_PATH.FileGroup
                Me.SelKey(enmUN.app_path).Contents = flnASSEMBLY_PATH
                Me.SelKey(enmUN.app_folder).Contents = flnASSEMBLY_FOLDER

                'enmUN.compiler_exe, enmUN.path take the first non-prefixed parameters; they are just file paths but without /parameter_name=
                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText, enmUN.compiler_exe, enmUN.path)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function 'InsFrom_Application

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCboard(ur_hdr As Boolean) As Integer
                ToCboard = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN

VBNetProject

DOC

  1. ~Clear Local
  2. ~Rebiuld Local
  3. dbUserInputMock
  4. DeveloperSettings
  5. MxBaseEc13
  6. VBNetScript


VBNetProject\~Clear Local

CodeLibrary VBCode WindowsCLI
rd /s /q bin
rd /s /q obj
pause

VBNetProject\~Rebiuld Local

CodeLibrary Extract VBCode
for %%f in (*.sln) do (
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
	
    for /D %%m in ("C:\Program Files (x86)\MSBuild\*\Bin\MSBuild.exe") do (
        "%%~m" /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
   )
:compile_complete
pause
del ..\Dep\*.exe
move bin\Release\*.exe ..\Dep
rd /s /q bin
rd /s /q obj
pause

VBNetProject\dbUserInputMock

CodeLibrary VBCode

Automatically convert the form to the dbUserInput class

Partial Public Class frmInput_1
    <System.Diagnostics.DebuggerHidden()>
    Public Shared Widening Operator CType(b As frmInput_1) As Mx.dbUserInput
        Return New Mx.dbUserInput(b, b.txtNotice_Message)
    End Operator
End Class 'frmInput_1

Setup the mock classes

  • Create flat classes that have the desired values
Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock
End Namespace 'Mx2
  • In a copy of the Mx.dbUserInput class, rename every System.Windows.Forms reference to Mx2.Mock
Option Strict On
Namespace Mx
    Public Class componentTextBox
        Private objTEXT_BOX As System.Windows.Forms.TextBox

        Public Sub New(ur_textbox As System.Windows.Forms.TextBox)
            objTEXT_BOX = ur_textbox
        End Sub

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objTEXT_BOX IsNot Nothing Then
                    Text = objTEXT_BOX.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objTEXT_BOX IsNot Nothing Then
                    objTEXT_BOX.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'componentTextBox

    Public Class dbUserInput
        Private objINPUT_FORM As System.Windows.Forms.Form
        Public txtNotice_Message As componentTextBox

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_input_form As System.Windows.Forms.Form, ur_notice_message_textbox As System.Windows.Forms.TextBox)
            objINPUT_FORM = ur_input_form
            Me.txtNotice_Message = New componentTextBox(ur_notice_message_textbox)
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Close()
            If objINPUT_FORM IsNot Nothing Then
                objINPUT_FORM.Close()
            End If
        End Sub

        Public Property BackColor As System.Drawing.Color
            <System.Diagnostics.DebuggerHidden()>
            Get
                BackColor = Nothing
                If objINPUT_FORM IsNot Nothing Then
                    BackColor = objINPUT_FORM.BackColor
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As System.Drawing.Color)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.BackColor = value
                End If
            End Set
        End Property 'BackColor

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objINPUT_FORM IsNot Nothing Then
                    Text = objINPUT_FORM.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'dbUserInput
End Namespace 'Mx

Create sample data

  • Load the mock dbUserInput with the testing state
Dim mockTextBox = New Mock.TextBox
Dim mockForm = New Mock.Form
Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
Call Mx.UserAction.Run_Script_errhnd(mockUserInput)
  • Compare the mock dbUserInput field changes to the expected result state
Dim strFOUND_RESULT = mockTextBox.Text
If strFOUND_RESULT = strEXPECTED_RESULT Then
	intPASS_COUNT += 1

Else
	intFAIL_COUNT += 1
	stpMOCK_REPORT.dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`").dLine())
End If 'strFOUND_RESULT

VBNetProject\DeveloperSettings

CodeLibrary VBCode

DeveloperSettings HTM

->

DeveloperSettings ZIP

->


VBNetProject\MxBaseEc13

CodeLibrary VBCode

MxBase Classes

->

Option Strict On
Namespace Mx '2020m01d03
    Public Module ConstVar
        Public Const mt = ""
        Public Const qs = """"
        Public Const qt = "'"
        Public Const s = " "

        <System.Diagnostics.DebuggerHidden()>
        Public Function AreEqual(ur_val As String, ur_cmp As String) As Boolean
            AreEqual = String.Equals(ur_val, ur_cmp, System.StringComparison.CurrentCultureIgnoreCase)
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b0(ur_val As Integer) As Integer
            b0 = ur_val - 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b1(ur_val As Integer) As Integer
            b1 = ur_val + 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function ContainingText(ur_large_text As String, ur_small_text As String) As Boolean
            ContainingText = InStr(ur_large_text, ur_small_text, CompareMethod.Text) > 0
        End Function 'ContainingText
        <System.Diagnostics.DebuggerHidden()>
        Public Function gUTF8_FileEncoding() As System.Text.UTF8Encoding
            gUTF8_FileEncoding = glbl.gUTF8_Encoding
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function EndingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            EndingWithText = AreEqual(Right(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'EndingWithText
        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText(ur_value As String) As Boolean
            HasText = Not String.IsNullOrWhiteSpace(ur_value)
        End Function 'HasText
        <System.Diagnostics.DebuggerHidden()>
        Public Function StartingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            StartingWithText = AreEqual(Left(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'StartingWithText

        <System.Diagnostics.DebuggerHidden()>
        Public Function CmdOutput(ur_exec_path As String, Optional ur_exec_param As String = mt) As String
            Dim objPCS As New System.Diagnostics.Process()
            With 1 : Dim prcINFO = objPCS.StartInfo
                prcINFO.FileName = ur_exec_path
                prcINFO.Arguments = ur_exec_param
                prcINFO.UseShellExecute = False
                prcINFO.RedirectStandardOutput = True
                prcINFO.CreateNoWindow = True
            End With 'prcINFO

            objPCS.Start()
            CmdOutput = objPCS.StandardOutput.ReadToEnd()
            objPCS.WaitForExit()
        End Function 'CmdOutput

        <System.Diagnostics.DebuggerHidden()>
        Public Function FileNamed() As MxText.FileName
            FileNamed = New MxText.FileName
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Strapd() As Strap
            Strapd = New Strap
        End Function

        Public Class glbl
            Private Shared objUTF8_ENCODING As System.Text.UTF8Encoding

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If objUTF8_ENCODING Is Nothing Then
                    objUTF8_ENCODING = New System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier:=False, throwOnInvalidBytes:=True)
                End If
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function gUTF8_Encoding() As System.Text.UTF8Encoding
                Call glbl.Init()
                gUTF8_Encoding = glbl.objUTF8_ENCODING
            End Function
        End Class 'glbl
    End Module 'ConstVar

    Public Class ErrListBase
        Dim pstpNOTICE_MSG As Strap

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            pstpNOTICE_MSG = Strapd()
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Function DoContinue() As Boolean
            DoContinue = (Me.Found = False)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            If pstpNOTICE_MSG.Length > 0 Then
                pstpNOTICE_MSG.dLine().dLine()
            End If

            pstpNOTICE_MSG.dLine(ur_exception.Message)
            pstpNOTICE_MSG.dLine(Strapd().d("Error in @r1.@r2").r1(ur_methodbase.DeclaringType.Name).r2(ur_methodbase.Name).dS("(status: @r1)").r1(ur_procedure_status))
        End Sub 'dError_Data

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Stack(ur_exception As System.Exception)
            Dim hr As Integer = System.Runtime.InteropServices.Marshal.GetHRForException(ur_exception)
            pstpNOTICE_MSG.dLine(ur_exception.GetType.ToString & "(0x" & hr.ToString("X8") & "): " & ur_exception.Message & System.Environment.NewLine & ur_exception.StackTrace & System.Environment.NewLine)
            Dim st = New System.Diagnostics.StackTrace(ur_exception, True)
            For Each objFRAME In st.GetFrames
                If objFRAME.GetFileLineNumber() > 0 Then
                    pstpNOTICE_MSG.dLine("Line:" & objFRAME.GetFileLineNumber() & " Filename: " & System.IO.Path.GetFileName(objFRAME.GetFileName) & System.Environment.NewLine)
                End If
            Next objFRAME
        End Sub 'dError_Stack

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function Found() As Boolean
            Found = (pstpNOTICE_MSG.Length > 0)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = pstpNOTICE_MSG
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Throw_Error_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            Call Me.dError_Data(ur_exception, ur_methodbase, ur_procedure_status)
            Throw New LocalException(mt)
        End Sub 'Throw_Error_Data


        Public Class LocalException
            Inherits System.Exception

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String)
                MyBase.New(message)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String, inner As System.Exception)
                MyBase.New(message, inner)
            End Sub
        End Class 'LocalException
    End Class 'ErrListBase

    Public Class iWrap(Of T)
        Public v As T

        Public Sub New(ur_t As T)
            Me.v = ur_t
        End Sub
    End Class 'iWrap

    Public Class ObaCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Obalist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list As Obalist(Of T) = Nothing)
            Call MyBase.New(prv.TotalItems(ur_list))
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObaCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property v() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObaCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function TotalItems(Optional ur_list As Obalist(Of T) = Nothing) As Integer
                TotalItems = 0
                If ur_list IsNot Nothing Then
                    TotalItems = ur_list.Count
                End If
            End Function 'TotalItems
        End Class 'prv
    End Class 'ObaCTR

    Public Class ObjCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Objlist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_list As Objlist(Of T))
            Call MyBase.New(ur_list.Count)
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObjCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property row() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                row = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObjCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function
    End Class 'ObjCTR

    Public Class Obalist(Of T)
        Private vobjLIST() As T

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list() As T = Nothing)
            Me.vobjLIST = ur_list
        End Sub

        Public ReadOnly Property Count() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Count = Me.vobjLIST.Length
            End Get
        End Property

        Public Property Item(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                Item = Me.vobjLIST(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.vobjLIST(ur_index) = ur_val
            End Set
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function kvp() As ObaCTR(Of T)
            kvp = New ObaCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Obalist

    Public Class Objlist(Of T)
        Inherits System.Collections.Generic.List(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As ObjCTR(Of T)
            kvp = New ObjCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Objlist

    Public Class SDPCTR(Of T As {New})
        Inherits RCTR

        Private vsdpLIST As SdPair(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdplist As SdPair(Of T))
            Call MyBase.New(ur_sdplist.Count)
            Me.vsdpLIST = ur_sdplist
        End Sub

        Public Shadows ReadOnly Property Current() As SDPCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDPCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property l() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = Me.vsdpLIST.l_enm(Me.Indexenm)
            End Get
        End Property

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdpLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDPCTR

    Public Class SdPair(Of T As {New})
        Inherits Sdata
        Private vobjT As System.Collections.Generic.Dictionary(Of String, T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            vobjT = New System.Collections.Generic.Dictionary(Of String, T)
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function d(ur_val As String, ur_link As T) As SdPair(Of T)
            d = Me
            Call Me.Add(ur_val)
            Call vobjT.Add(ur_val, ur_link)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDPCTR(Of T)
            kvp = New SDPCTR(Of T)(Me)
        End Function

        Public Property l(ur_key As String) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = vobjT.Item(ur_key)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(ur_key) = ur_val
            End Set
        End Property

        Public Property l_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_b1 = vobjT.Item(Me.v_b1(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_b1(ur_index)) = ur_val
            End Set
        End Property

        Public Property l_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_enm = vobjT.Item(Me.v_enm(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_enm(ur_index)) = ur_val
            End Set
        End Property
    End Class 'SdPair

    Public Class RCTR
        Private pintMAX_NUM As Integer
        Private pintCUR_NUM As Integer

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(ByVal b As RCTR) As Integer
            Return b.Indexb1
        End Operator 'CType

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_max_num As Integer)
            Me.pintMAX_NUM = ur_max_num
        End Sub

        Public Shadows ReadOnly Property Current() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me.pintCUR_NUM
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function GetEnumerator() As RCTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public ReadOnly Property Indexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexb1 = Me.pintCUR_NUM
            End Get
        End Property

        Public ReadOnly Property Indexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexenm = b0(Me.pintCUR_NUM)
            End Get
        End Property

        Public ReadOnly Property LastIndexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexb1 = Me.pintMAX_NUM
            End Get
        End Property

        Public ReadOnly Property LastIndexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexenm = b0(Me.pintMAX_NUM)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function MoveNext() As Boolean
            MoveNext = (Me.pintCUR_NUM < Me.pintMAX_NUM)
            Me.pintCUR_NUM += 1
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Reset() As RCTR
            Reset = Me
            Me.pintCUR_NUM = 0
        End Function
    End Class 'RCTR

    Public Class SDACTR
        Inherits RCTR

        Private psdaLIST As Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdata As Sdata)
            Call MyBase.New(ur_sdata.Count)
            Me.psdaLIST = ur_sdata
        End Sub

        Public Shadows ReadOnly Property Current() As SDACTR
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDACTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.psdaLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDACTR

    Public Class Sdata
        Inherits System.Collections.Generic.List(Of String)

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_val As String) As Sdata
            d = Me
            Call Me.Add(ur_val)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ParamArray ur_val() As String) As Sdata
            dList = Me
            If ur_val IsNot Nothing Then
                For Each strENTRY In ur_val
                    If strENTRY Is Nothing Then
                        strENTRY = mt
                    End If

                    Call Me.Add(strENTRY)
                Next strENTRY
            End If
        End Function 'dList

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As Sdata
            gCopy = New Sdata().dList(Me.ToArray)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDACTR
            kvp = New SDACTR(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Split(ur_text As String, ur_sprtr As Char) As Sdata
            Dim sdaCMP = New Sdata
            Split = sdaCMP
            For Each strTEXT In ur_text.Split(ur_sprtr)
                sdaCMP.Add(strTEXT)
            Next
        End Function 'Split

        Public Property v_b1(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property v_enm(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Sdata

    Public Class Strap
        Private pstbTEXT As System.Text.StringBuilder

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            Me.pstbTEXT = New System.Text.StringBuilder
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(b As Strap) As String
            Return b.ToString
        End Operator

        <System.Diagnostics.DebuggerHidden()>
        Public Function Clear() As Strap
            Clear = Me
            Call Me.pstbTEXT.Clear()
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_text As String) As Strap
            d = Me.dSprtr(mt, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSV_Quoted(ur_index_b1 As Integer, ur_text As String) As Strap
            dCSV_Quoted = Me
            If ur_index_b1 > 1 Then
                Me.d(",")
            End If

            Me.d(qs).d(ur_text.Replace(qs, qs & qs)).d(qs)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ur_sprtr As String, ParamArray ur_text() As String) As Strap
            dList = Me
            If ur_text IsNot Nothing Then
                For Each strENTRY In ur_text
                    Call Me.dSprtr(ur_sprtr, strENTRY)
                Next strENTRY
            End If
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSVList(ParamArray ur_text() As String) As Strap
            dCSVList = Me
            If ur_text IsNot Nothing Then
                For ENTCTR = 0 To UBound(ur_text)
                    Me.dCSV_Quoted(ENTCTR + 1, ur_text(ENTCTR))
                Next ENTCTR
            End If
        End Function 'dCSVList

        <System.Diagnostics.DebuggerHidden()>
        Public Function dLine(Optional ur_text As String = "") As Strap
            dLine = Me.dSprtr(vbCrLf, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dS(ur_text As String) As Strap
            dS = Me.dSprtr(s, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dSprtr(ur_sprtr As String, ur_text As String) As Strap
            dSprtr = Me
            Me.pstbTEXT.Append(ur_sprtr).Append(ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function gCopy(ur_text As String) As Strap
            gCopy = New Strap().d(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText() As Boolean
            HasText = (Me.Length > 0)
        End Function

        Public ReadOnly Property Length As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Length = Me.pstbTEXT.Length
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function r1(ur_text As String) As Strap
            r1 = Me
            Call Me.pstbTEXT.Replace("@r1", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function r2(ur_text As String) As Strap
            r2 = Me
            Call Me.pstbTEXT.Replace("@r2", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function rx(ur_index As Integer, ur_text As String) As Strap
            rx = Me
            Call Me.pstbTEXT.Replace("@r" & ur_index, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = Me.pstbTEXT.ToString
        End Function
    End Class 'Strap

    Public Class bitBASE
        Public name As String
        Public seq As Integer
    End Class

    Public Class TRow(Of T As {New, bitBASE})
        Inherits Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            For Each intVAL In Me.RefColNames
                Me.Add(mt)
            Next
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Index_TableSplit(ur_table As Objlist(Of TRow(Of T)), ur_key As T) As SdPair(Of Objlist(Of TRow(Of T)))
            Dim sdpRET = New SdPair(Of Objlist(Of TRow(Of T)))
            Index_TableSplit = sdpRET
            Dim tblCHUNK As Objlist(Of TRow(Of T)) = Nothing
            For Each rowCHUNK In ur_table
                Dim strINDEX = rowCHUNK.v(ur_key)
                Dim intFOUND = sdpRET.IndexOf(strINDEX)
                If intFOUND < 0 Then
                    tblCHUNK = New Objlist(Of TRow(Of T))
                    sdpRET.d(strINDEX, tblCHUNK)
                Else
                    tblCHUNK = sdpRET.l_enm(intFOUND)
                End If

                tblCHUNK.Add(rowCHUNK)
            Next rowCHUNK

            Call sdpRET.Sort()
        End Function 'Index_TableSplit


        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As TRow(Of T)
            Dim sdaRET = New TRow(Of T)
            gCopy = sdaRET
            For Each kvpENTRY In Me.kvp
                sdaRET.v_enm(kvpENTRY.Indexenm) = kvpENTRY.v
            Next kvpENTRY
        End Function

        Public Function Link_Table(ur_table As Objlist(Of TRow(Of T)), ParamArray ur_key_list() As T) As Objlist(Of TRow(Of T))
            Dim tblRET = New Objlist(Of TRow(Of T))
            Link_Table = tblRET
            For Each rowCHUNK In ur_table
                Dim bolFOUND = True
                For Each intKEY In ur_key_list
                    If AreEqual(rowCHUNK.v(intKEY), Me.v(intKEY)) = False Then
                        bolFOUND = False
                        Exit For
                    End If
                Next intKEY

                If bolFOUND Then
                    tblRET.Add(rowCHUNK)
                End If
            Next rowCHUNK
        End Function 'Link_Table

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function PersistRead(ur_persist_path As String) As Objlist(Of TRow(Of T))
            Dim ttbRET = New Objlist(Of TRow(Of T))
            PersistRead = ttbRET
            If Mx.glbl.gWindowsFS.HasFile(ur_persist_path) Then
                Dim bolFIRST_LINE = True
                Dim lstREF_COL = New Objlist(Of T)
                Using stmIN_FILE = Mx.glbl.gWindowsFS.ReadStream(ur_persist_path)
                    Dim strLINE = mt
                    While stmIN_FILE.EndOfStream = False
                        strLINE &= stmIN_FILE.ReadLine
                        Dim bolBALANCED_QUOTES = True
                        For CHRCTR = 0 To strLINE.Length - 1
                            If strLINE(CHRCTR) = """"c Then
                                bolBALANCED_QUOTES = Not bolBALANCED_QUOTES
                            End If
                        Next CHRCTR

                        If bolBALANCED_QUOTES = False Then
                            strLINE &= vbCrLf

                        Else
                            Dim new_row = New TRow(Of T)
                            If Left(strLINE, 1) = vbLf Then
                                strLINE = Mid(strLINE, 2)
                            End If

                            If bolFIRST_LINE = True Then
                                bolFIRST_LINE = False
                                Dim bolCOL_MATCH = False
                                Dim sdaFIRST_ROW = MxText.CSVSplit(strLINE, vbTab)
                                For Each strENTRY In MxText.CSVSplit(strLINE, vbTab)
                                    Dim enmFOUND_KEY As T = Nothing
                                    For Each enmKEY In new_row.RefColKeys
                                        If AreEqual(enmKEY.name, strENTRY) Then
                                            enmFOUND_KEY = enmKEY
                                            bolCOL_MATCH = True
                                            Exit For
                                        End If
                                    Next enmKEY

                                    lstREF_COL.Add(enmFOUND_KEY)
                                Next strENTRY

                                If bolCOL_MATCH = False Then
                                    Exit While
                                End If

                            ElseIf HasText(strLINE) Then
                                For Each kvpCOL In MxText.CSVSplit(strLINE, vbTab).kvp
                                    Dim enmKEY = lstREF_COL.Item(kvpCOL.Indexenm)
                                    If enmKEY IsNot Nothing Then
                                        new_row.v(enmKEY) = kvpCOL.v
                                    End If
                                Next kvpCOL

                                ttbRET.Add(new_row)
                            End If 'bolFIRST_LINE

                            strLINE = mt
                        End If 'bolBALANCED_QUOTES
                    End While
                End Using 'stmIN_FILE
            End If 'ur_persist_path
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Sub PersistWrite(ur_table As Objlist(Of TRow(Of T)), ur_persist_path As MxText.FileName)
            If Mx.glbl.gWindowsFS.HasDir(ur_persist_path.gParentDir) = False Then
                Mx.glbl.gWindowsFS.CreateDirectory(ur_persist_path.gParentDir)
            End If

            Using stmOUT_FILE = Mx.glbl.gWindowsFS.WriteStream(ur_persist_path)
                For Each kvpROW In ur_table.kvp
                    stmOUT_FILE.Write(kvpROW.row.ToString(kvpROW.Indexb1 = 1, True))
                Next
            End Using 'stmOUT_FILE
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeys() As Objlist(Of T)
            RefColKeys = TRow(Of T).glbl.RefKeys
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeySearch(ur_name As String) As Objlist(Of T)
            RefColKeySearch = TRow(Of T).glbl.RefKeySearch(ur_name)
        End Function 'RefColKeySearch

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColNames() As Sdata
            RefColNames = TRow(Of T).glbl.RefNames
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ToCbrd(ur_hdr As Boolean) As Integer
            ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean, Optional ur_quoted As Boolean = False) As Strap
            Dim stpRET = New Strap
            ToString = stpRET
            If ur_hdr Then : For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : stpRET.d(kvpCOL.v) : Next kvpCOL : stpRET.dLine() : End If
            For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : If ur_quoted Then : stpRET.d(qs).d(Me.v_enm(kvpCOL.Indexenm).Replace(qs, qs & qs)).d(qs) : Else : stpRET.d(Me.v_enm(kvpCOL.Indexenm)) : End If : Next kvpCOL : stpRET.dLine()
        End Function


        Public Property v(ur_cl As T) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.Item(ur_cl.seq)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = ""
                End If

                Me.Item(ur_cl.seq) = ur_val
            End Set
        End Property

        Public Class glbl
            Private Shared sdaTCOL_NAME As Sdata
            Private Shared sdjTCOL_KEY As Objlist(Of T)

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME Is Nothing Then
                    Dim objTEST = GetType(T).GetFields()(0).GetValue(Nothing)
                End If

                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME IsNot Nothing Then
                    sdjTCOL_KEY = New Objlist(Of T)
                    Dim tpeCMP = GetType(T)
                    For Each kvpCOL In sdaTCOL_NAME.kvp
                        For Each objPROP In tpeCMP.GetFields()
                            If tpeCMP.DeclaringType Is tpeCMP Then
                                Dim objBIT = DirectCast(objPROP.GetValue(Nothing), bitBASE)
                                If objBIT.seq = kvpCOL.Indexenm Then
                                    sdjTCOL_KEY.Add(DirectCast(objPROP.GetValue(Nothing), T))
                                    Exit For
                                End If
                            End If 'tpeCMP
                        Next objPROP
                    Next kvpCOL
                End If 'sdaTCOL_NAME
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Function NewProp() As T
                Dim objRET = New T
                NewProp = objRET

                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Function 'NewProp

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub NewProp(ur_prop As T)
                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function NewBitBase() As T
                NewBitBase = glbl.NewProp()
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub NewBitBase(ur_prop As T)
                Call glbl.NewProp(ur_prop)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeys() As Objlist(Of T)
                Call glbl.Init()
                RefKeys = glbl.sdjTCOL_KEY
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeySearch(ur_name As String) As Objlist(Of T)
                Call glbl.Init()
                Dim ttbRET = New Objlist(Of T)
                RefKeySearch = ttbRET
                Dim intFOUND_INDEX = TRow(Of T).glbl.RefNames.IndexOf(ur_name)
                If intFOUND_INDEX >= b0(1) Then
                    ttbRET.Add(TRow(Of T).glbl.RefKeys(intFOUND_INDEX))
                End If
            End Function 'RefKeySearch

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefNames() As Sdata
                Call glbl.Init()
                RefNames = glbl.sdaTCOL_NAME
            End Function

            Public Class Trbase(Of W As {New, T})
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function NewBitBase() As W
                    Dim objRET = New W
                    NewBitBase = objRET
                    Call TRow(Of T).glbl.NewBitBase(objRET)
                End Function
            End Class 'Trbase
        End Class 'glbl
    End Class 'Trow

    Partial Public Class MxText 'Parse
        Public Class enmCMD_RET
            Inherits bitBASE
            Public Shared eq As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared fslash As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs_end As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared txt As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared unk As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared ws As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
        End Class

        Public Class Cmdline_UB(Of T As {New, bitBASE}, W As {New, bitBASE})
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                CommandLine_UBParm = prv.CommandLine_UBParm(ur_ub_key, ur_ub_val, ur_source_text, ur_default_field_list)
            End Function

            Class sCMDLINE
                Inherits Mx.Objlist(Of TRow(Of enmCMD_RET))

                <System.Diagnostics.DebuggerHidden()>
                Public Overloads Function ToString(ur_hdr As Boolean) As String
                    Dim stpRET = Strapd() : For Each kvpREC In Me.kvp : stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr)) : Next kvpREC : ToString = stpRET
                End Function 'ToString
                <System.Diagnostics.DebuggerHidden()>
                Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                End Function
            End Class 'sCMDLINE

            Class sCMD_RET
                Public ttbUB_PARM As Objlist(Of TRow(Of W))
                Public ttbCMD_PARM As sCMDLINE
            End Class

            Partial Private Class prv
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                    Dim objRET = New sCMD_RET
                    CommandLine_UBParm = objRET
                    objRET.ttbUB_PARM = New Objlist(Of TRow(Of W))
                    objRET.ttbCMD_PARM = New sCMDLINE
                    Dim rowCMD_PARM = New TRow(Of enmCMD_RET)
                    objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                    Dim sdaDEFAULT_PARMNAME = New Sdata
                    Dim sdaDEST_PARMS = TRow(Of T).glbl.RefNames
                    For Each intUN In ur_default_field_list
                        sdaDEFAULT_PARMNAME.d(intUN.name)
                    Next

                    Dim stpCOMPILE = Strapd()
                    Dim intPREV_CHUNK = enmCMD_RET.ws
                    Dim intCHUNK_C = enmCMD_RET.ws
                    For CHRCTR = 0 To ur_source_text.Length - 1
                        Dim chrC = ur_source_text(CHRCTR)
                        intCHUNK_C = gChunkType(chrC)
                        Dim intSPAN = 1
                        For SPNCTR = CHRCTR + 1 To ur_source_text.Length - 1
                            Dim chrS = ur_source_text(SPNCTR)
                            Dim intSPAN_C = gChunkType(chrS)
                            If intSPAN_C IsNot intCHUNK_C OrElse
                              intSPAN_C Is enmCMD_RET.qs Then
                                'Combine all chunks except for escaped quotes
                                intSPAN = SPNCTR - CHRCTR
                                Exit For
                            End If

                            If SPNCTR = ur_source_text.Length - 1 Then
                                intSPAN = SPNCTR + 1 - CHRCTR
                                Exit For
                            End If
                        Next SPNCTR

                        Dim strCHUNK = ur_source_text.Substring(CHRCTR, intSPAN)
                        If intPREV_CHUNK Is enmCMD_RET.ws Then
                            'Have ws, skip compiled ws; wait for fslash or default parm
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'skip compiled fslash
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip ws between parameters

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'compile unquoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = enmCMD_RET.txt
                                stpCOMPILE.Clear.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.fslash Then
                            'Have ws-fslash, compile txt parm name; wait for eq
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'qs between parm name and eq is unk
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq Then
                                'skip compile qe
                                rowCMD_PARM.v(enmCMD_RET.fslash) = stpCOMPILE.ToString
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = enmCMD_RET.eq

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'compile txt into parm name
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.eq Then
                            'Have ws-fslash-eq, skip compile; wait for txt
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'flush parameter as "=true"; start new parameter
                                stpCOMPILE.Clear.d("true")
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted parameter value
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'keep ws in eq

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'skip eq between paramater name and value

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'store param name, compile unquoted parameter value
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.txt Then
                            'Have ws-fslash-eq-txt, compile parm val; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                'Keep fslash and qs in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'Keep eq in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs Then
                            'Have ws-fslash-eq-qs, compile parm val; wait for qs_end
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'Keep fslash in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'hold parameter; skip this qs and look for another escaped qs or flush the parameter
                                intPREV_CHUNK = enmCMD_RET.qs_end

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'Keep ws, eq and txt in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs_end Then
                            'Have ws-fslash-eq-qs-qsend, compile parm val without ending quote; wait for qs or ws
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'qs_end then fslash without ws between is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'keep escaped qs
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'qs_end then ws or txt is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.unk Then
                            'Have unk, skip compile; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip parameter; start new parameter
                                rowCMD_PARM.v(enmCMD_RET.txt) = stpCOMPILE.ToString
                                rowCMD_PARM = New TRow(Of enmCMD_RET)
                                objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If
                        End If

                        CHRCTR += intSPAN - 1

                        If CHRCTR = ur_source_text.Length - 1 Then
                            'On last entry
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse intCHUNK_C Is enmCMD_RET.eq Then
                                'flush default parameter value
                                stpCOMPILE.Clear.d("true")
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs OrElse intCHUNK_C Is enmCMD_RET.txt Then
                                'flush parameter
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip trailing ws
                            End If
                        End If
                    Next CHRCTR
                End Function 'CommandLine_Chunk

                Private Class Flush_Ret
                    Public rowCMD_PARM As TRow(Of enmCMD_RET)
                    Public intPREV_CHUNK As enmCMD_RET
                End Class

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function Flush_Parameter(ur_ub_key As W, ur_ub_val As W, ur_cmdparm_row As TRow(Of enmCMD_RET), ur_parm_val As Strap, ur_new_prevchunk As enmCMD_RET, ur_refname_list As Sdata, ur_objret_arl As sCMD_RET) As Flush_Ret
                    Dim objRET = New Flush_Ret
                    Flush_Parameter = objRET
                    objRET.rowCMD_PARM = New TRow(Of enmCMD_RET)
                    ur_objret_arl.ttbCMD_PARM.Add(objRET.rowCMD_PARM)
                    objRET.intPREV_CHUNK = ur_new_prevchunk
                    'flush parameter
                    ur_cmdparm_row.v(enmCMD_RET.txt) = ur_parm_val
                    Dim intFOUND = ur_refname_list.IndexOf(ur_cmdparm_row.v(enmCMD_RET.fslash).ToLower)
                    If intFOUND >= 0 Then
                        With 1 : Dim sdaROW = New TRow(Of W)
                            sdaROW.v(ur_ub_key) = ur_refname_list.v_enm(intFOUND)
                            sdaROW.v(ur_ub_val) = ur_cmdparm_row.v(enmCMD_RET.txt)
                            ur_objret_arl.ttbUB_PARM.Add(sdaROW)
                        End With

                        'Skip parameter if not found
                    End If

                    ur_parm_val.Clear()
                End Function

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function gChunkType(ur_char As Char) As enmCMD_RET
                    If ur_char = vbCr OrElse
                  ur_char = vbLf OrElse
                  ur_char = " "c OrElse
                  ur_char = vbTab Then
                        gChunkType = enmCMD_RET.ws

                    ElseIf ur_char = "="c OrElse
                  ur_char = ":"c Then
                        gChunkType = enmCMD_RET.eq

                    ElseIf ur_char = "/"c Then
                        gChunkType = enmCMD_RET.fslash

                    ElseIf ur_char = """"c Then
                        gChunkType = enmCMD_RET.qs

                    Else
                        gChunkType = enmCMD_RET.txt
                    End If
                End Function 'gChunkType
            End Class 'prv
        End Class
    End Class 'MxText-Parse

    Partial Public Class MxText
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function CSVSplit(ByVal ur_line As String, Optional ur_separator As String = ",") As Sdata
            Dim sdaCMP = New Sdata
            CSVSplit = sdaCMP
            Dim objARRAY = ur_line.ToCharArray
            Dim objSPRTR = Mid(ur_separator, 1, 1).ToCharArray()(0)
            Dim objESCAPE_QUOTE = """"c

            Const cstSTART = 0
            Const cstESC = 1
            Const cstQS = 2
            Dim intPARSE_STATE = cstSTART
            Dim intLEN = Len(ur_line) - 1
            Dim stpFIELD As New Strap
            For intIX = 0 To intLEN
                Dim objCHR = objARRAY(intIX)
                Select Case intPARSE_STATE
                    Case cstESC
                        stpFIELD.d(objCHR)
                        intPARSE_STATE = cstQS

                    Case cstQS
                        If objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstSTART
                            Dim intNEXT_IX = intIX + 1
                            If intNEXT_IX < intLEN Then
                                If objARRAY(intNEXT_IX) = objESCAPE_QUOTE Then
                                    intPARSE_STATE = cstESC
                                End If 'intNEXT_IX
                            End If 'intNEXT_IX

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR

                    Case cstSTART
                        If objCHR = objSPRTR Then
                            sdaCMP.d(stpFIELD.ToString)
                            Call stpFIELD.Clear()

                        ElseIf objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstQS

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR
                End Select 'intPARSE_STATE
            Next intIX

            sdaCMP.d(stpFIELD)
        End Function 'CSVSplit
    End Class 'MxText-Csv

    Public Class MxText
        Public Class FileName
            Public FilePath As String
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.FilePath = mt
            End Sub 'New
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(ur_path As String)
                Me.FilePath = ur_path
            End Sub 'New

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As FileName) As String
                Return b.FilePath
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As String) As FileName
                Return New FileName(b)
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shadows Function ToString() As String
                ToString = Me.FilePath
            End Function 'ToString

            <System.Diagnostics.DebuggerHidden()>
            Public Function dAppendEXT(ur_ext As String) As FileName
                dAppendEXT = Me
                If ur_ext.StartsWith(".") = False Then
                    ur_ext = "." & ur_ext
                End If

                Me.FilePath &= ur_ext
            End Function 'dAppendEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function d(ur_file_name As String) As FileName
                d = Me
                If HasText(Me.FilePath) Then
                    Me.FilePath = System.IO.Path.Combine(Me.FilePath, ur_file_name)

                Else 'Me
                    Me.FilePath = ur_file_name
                End If 'Me
            End Function 'd

            <System.Diagnostics.DebuggerHidden()>
            Public Function dNowTextYMDHMS(ur_file_name As String, Optional ur_separator As String = "_") As FileName
                dNowTextYMDHMS = Me
                Me.d(ur_file_name & ur_separator & Now().ToString("yyyy\mMM\dddthh\mmm\sss").Replace("P12", "N12").Replace("A12", "A00").ToLower)
            End Function 'dNowTextYMDHMS

            Public Property Ext() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Ext = System.IO.Path.GetExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wEXT(value)
                End Set
            End Property 'Ext

            Public ReadOnly Property ExtAll() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ExtAll = Strapd().dList(mt, Me.ExtList.ToArray)
                End Get
            End Property 'ExtAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function ExtList() As Sdata
                Dim sdaDESC = Sdata.Split(Me.FilePath, "."c)
                ExtList = sdaDESC
                sdaDESC.RemoveAt(0)
                For Each ROWCTR In sdaDESC.kvp
                    sdaDESC.v_b1(ROWCTR) = "." & sdaDESC.v_b1(ROWCTR)
                Next ROWCTR
            End Function 'ExtList

            Public Property FileGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileGroup = System.IO.Path.GetFileNameWithoutExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.Ext
                End Set
            End Property 'FileGroup

            Public Property FileBaseGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileBaseGroup = mt
                    For Each strENTRY In Sdata.Split(Me.Name, "."c)
                        FileBaseGroup = strENTRY
                        Exit For
                    Next
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.ExtAll
                End Set
            End Property 'FileBaseGroup

            <System.Diagnostics.DebuggerHidden()>
            Public Function gCopy() As FileName
                gCopy = New FileName(Me)
            End Function 'gCopy

            <System.Diagnostics.DebuggerHidden()>
            Public Function gFullPath() As FileName
                gFullPath = New FileName(glbl.gWindowsFS.GetFullPath(Me.FilePath))
            End Function 'gFullPath

            <System.Diagnostics.DebuggerHidden()>
            Public Function gParentDir() As FileName
                gParentDir = New FileName(Me.ParentDir)
            End Function 'gParentDir

            Public Property Name() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Name = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If

                    If HasText(strPATH) Then
                        Name = System.IO.Path.GetFileName(strPATH)
                    End If
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wParentDir.d(value)
                End Set
            End Property 'Name

            Public Property ParentDir() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ParentDir = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If 'strPATH

                    If HasText(strPATH) Then
                        ParentDir = System.IO.Path.GetDirectoryName(strPATH)
                    End If 'strPATH
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Dim strFILE_NAME = Me.Name
                    If HasText(value) Then
                        Me.FilePath = System.IO.Path.Combine(value, strFILE_NAME)

                    Else 'value
                        Me.FilePath = strFILE_NAME
                    End If 'value
                End Set
            End Property 'ParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function ParentList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH = Me.PathList
                ParentList = sdaPATH
                sdaPATH.RemoveAt(b0(sdaPATH.Count))
            End Function 'ParentList

            <System.Diagnostics.DebuggerHidden()>
            Public Function PathList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH As New System.Collections.Generic.List(Of FileName)
                PathList = sdaPATH

                Dim sdaDESC = New Objlist(Of FileName)
                sdaDESC.Add(Me.gCopy)
                Dim objREDUCE = Me.gCopy
                Call objREDUCE.wParentDir()
                While HasText(objREDUCE.FilePath)
                    sdaDESC.Add(objREDUCE.gCopy)
                    Call objREDUCE.wParentDir()
                End While 'objREDUCE

                For Each objFILE In sdaDESC
                    sdaPATH.Add(objFILE)
                Next objFILE
            End Function 'PathList

            <System.Diagnostics.DebuggerHidden()>
            Public Function wAssemblyDir(ur_assembly_info As Microsoft.VisualBasic.ApplicationServices.AssemblyInfo) As FileName
                wAssemblyDir = Me
                Me.FilePath = ur_assembly_info.DirectoryPath.Replace("\bin\Debug", mt)
            End Function 'wAssemblyDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wClear() As FileName
                wClear = Me
                Me.FilePath = mt
            End Function 'wClear

            <System.Diagnostics.DebuggerHidden()>
            Public Function wEXT(ur_ext As String) As FileName
                wEXT = Me
                Dim strFILE_NAME = Me.FileGroup
                If Left(ur_ext, 1) <> "." Then
                    ur_ext = "." & ur_ext
                End If 'ur_ext

                Me.wParentDir.d(strFILE_NAME & ur_ext)
            End Function 'wEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function wParentDir() As FileName
                wParentDir = Me
                Me.FilePath = Me.ParentDir
            End Function 'wParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wTempFileName(ur_fs_proxy As Microsoft.VisualBasic.MyServices.FileSystemProxy) As FileName
                wTempFileName = Me
                Me.FilePath = ur_fs_proxy.GetTempFileName
                Call ur_fs_proxy.DeleteFile(Me.FilePath)
            End Function 'wTempFileName
        End Class 'FileName
    End Class 'MxText-FileName

    Partial Public Class glbl
        Public Class gCboard
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Clear()
                Call My.Computer.Clipboard.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetText() As String
                GetText = My.Computer.Clipboard.GetText
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function SetText(ur_text As String) As Integer
                If HasText(ur_text) Then
                    Call My.Computer.Clipboard.SetText(ur_text)
                    SetText = 1 + ur_text.Length - ur_text.Replace(vbLf, mt).Length
                Else
                    Call My.Computer.Clipboard.Clear()
                    SetText = 0
                End If
            End Function 'SetText
        End Class 'gCboard

        Public Class gDiagnostics
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function IsRunningWindow(ur_title As String) As Boolean
                IsRunningWindow = False
                For Each objCUR_PROC In System.Diagnostics.Process.GetProcesses()
                    If objCUR_PROC.MainWindowHandle.ToInt32 <> 0 AndAlso
                      AreEqual(objCUR_PROC.MainWindowTitle, ur_title) Then
                        IsRunningWindow = True
                        Exit For
                    End If
                Next objCUR_PROC
            End Function 'IsRunningWindow

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Read_CommandLineText(ur_exec_path As String, ur_exec_param As String) As String
                Dim prcCOMMAND_LINE = gDiagnostics.Start_CommandLine_Program(ur_exec_path, ur_exec_param)
                Read_CommandLineText = prcCOMMAND_LINE.StandardOutput.ReadToEnd()
                prcCOMMAND_LINE.WaitForExit()
            End Function 'Read_CommandLineText

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Start_CommandLine_Program(ur_exec_path As String, ur_exec_param As String) As System.Diagnostics.Process
                Dim retPROCESS As New System.Diagnostics.Process()
                Start_CommandLine_Program = retPROCESS
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.UseShellExecute = False
                    prcINFO.RedirectStandardOutput = True
                    prcINFO.RedirectStandardError = True
                    prcINFO.CreateNoWindow = True
                End With 'prcINFO

                retPROCESS.Start()
            End Function 'Start_Procses

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Start_Windows_Program(ur_exec_path As String, ur_exec_param As String)
                Dim retPROCESS As New System.Diagnostics.Process()
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.Verb = "Open"
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
                    prcINFO.UseShellExecute = True
                End With 'prcINFO

                retPROCESS.Start()
            End Sub 'Start_Procses
        End Class 'gDiagnostics

        Public Class gInteraction
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub AppActivate(ur_window_title As String)
                Microsoft.VisualBasic.Interaction.AppActivate(ur_window_title)
            End Sub
        End Class 'gInteraction

        Public Class gEnvironment
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine() As String
                CommandLine = System.Environment.CommandLine
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ExpandEnvironmentVariables(ur_path As String) As String
                ExpandEnvironmentVariables = System.Environment.ExpandEnvironmentVariables(ur_path)
            End Function
        End Class 'gEnvironment

        Public Class gMsgBox
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetResult(ur_message As String, ur_style As MsgBoxStyle, ur_title As String) As MsgBoxResult
                GetResult = MsgBox(ur_message, ur_style, ur_title)
            End Function
        End Class 'gMsgBox

        Public Class gThread
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Sleep(ur_milliseconds As Integer)
                System.Threading.Thread.Sleep(ur_milliseconds)
            End Sub
        End Class 'gThread

        Public Class gWindowsFS
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Copy(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Copy(ur_source_path, ur_dest_path, True)
            End Sub
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub CreateDirectory(ur_folder_path As String)
                System.IO.Directory.CreateDirectory(ur_folder_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Delete(ur_path As String)
                System.IO.File.Delete(ur_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = System.IO.Directory.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetDirectories(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetDirectories = System.IO.Directory.GetDirectories(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFullPath(ur_partial_path As String) As String
                GetFullPath = System.IO.Path.GetFullPath(ur_partial_path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasDir(ur_search_folder As String) As Boolean
                HasDir = System.IO.Directory.Exists(ur_search_folder)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasFile(ur_search_Path As String) As Boolean
                HasFile = System.IO.File.Exists(ur_search_Path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Move(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Move(ur_source_path, ur_dest_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadAllText(ur_file_path As String) As String
                ReadAllText = System.IO.File.ReadAllText(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadStream(ur_file_path As String) As System.IO.StreamReader
                ReadStream = New System.IO.StreamReader(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub WriteAllText(ur_file_path As String, ur_text As String)
                Call System.IO.File.WriteAllText(ur_file_path, ur_text, Mx.gUTF8_FileEncoding())
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function WriteStream(ur_file_path As String) As System.IO.StreamWriter
                WriteStream = New System.IO.StreamWriter(ur_file_path, False, Mx.gUTF8_FileEncoding())
            End Function
        End Class 'gWindowsFS
    End Class 'glbl

    Public Class TablePKEnum(Of E As {New, bitBASE}, P As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of P, T)
        Private PK As E

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_flag_populate_keys As Boolean = True)
            Me.ttb = New System.Collections.Generic.Dictionary(Of P, T)
            Me.PK = TRow(Of E).glbl.RefKeys.tr_b1(1)
            If ur_flag_populate_keys Then
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    Dim new_row = New T
                    new_row.v(Me.PK) = enmENTRY.name
                    Me.ttb.Add(enmENTRY, new_row)
                Next enmENTRY
            End If 'ur_empty_table
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ur_key As P) As Boolean
            ExistsKey = Me.ttb.ContainsKey(ur_key)
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim enmENTRY = prv.Get_PKStr(Me, ur_row)
            If enmENTRY Is Nothing Then
                Throw New System.Exception("Primary Key must exist in the enumeration: " & ur_row.v(Me.PK))

            ElseIf Me.ttb.ContainsKey(enmENTRY) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_row.v(Me.PK))

            Else
                Me.ttb.Add(enmENTRY, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            InsKey = ret
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKEnum(Of E, P, T)
            Dim ttbRET = New TablePKEnum(Of E, P, T)
            PersistRead = ttbRET
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Me.Ins(CType(row, T))
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T()
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ur_key As P) As T
            SelKey = Me.ttb.Item(ur_key)
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                ret = Me.ttb.Item(ur_key)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            UseKey = ret
        End Function 'UseKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        Private Class prv
            Public Shared Sub Assign_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T, ur_key As P)
                ur_row.v(ur_table.PK) = ur_key.name
            End Sub 'Assign_PKStr

            Public Shared Function Get_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T) As P
                Dim ret As P = Nothing
                Dim strPK = ur_row.v(ur_table.PK)
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    If AreEqual(enmENTRY.name, strPK) Then
                        ret = enmENTRY
                        Exit For
                    End If
                Next enmENTRY

                Get_PKStr = ret
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKEnum

    Public Class TablePKStr(Of E As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of String, T)
        Private PK As Objlist(Of E)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_pk_count As Integer)
            Me.ttb = New System.Collections.Generic.Dictionary(Of String, T)
            Me.PK = New Objlist(Of E)
            With 1 : Dim lstKEYS = TRow(Of E).glbl.RefKeys
                Dim intPK_COUNT = ur_pk_count
                If intPK_COUNT > lstKEYS.Count Then
                    intPK_COUNT = lstKEYS.Count
                End If

                For KEYCTR = 1 To ur_pk_count
                    Me.PK.Add(lstKEYS.Item(b0(KEYCTR)))
                Next
            End With 'lstKEYS
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ParamArray ur_key() As String) As Boolean
            ExistsKey = False
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("ExistsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                ExistsKey = Me.ttb.ContainsKey(strPK_KEY_COMBINED)
            End If 'ur_key
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function DelAll() As TablePKStr(Of E, T)
            DelAll = Me
            Call Me.ttb.Clear()
        End Function 'DelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_row)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

            Else
                Me.ttb.Add(strPK_KEY_COMBINED, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("InsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

                Else
                    ret = New T
                    Call prv.Assign_PKStr(Me, ret, ur_key)
                    Me.ttb.Add(strPK_KEY_COMBINED, ret)
                End If 'Me
            End If 'ur_key

            InsKey = ret
        End Function 'InsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKStr(Of E, T)
            PersistRead = Me
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Dim new_row = New T
                For Each enmENTRY In new_row.RefColKeys
                    new_row.v(enmENTRY) = row.v(enmENTRY)
                Next

                Me.Ins(new_row)
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("SelKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    ret = Me.ttb.Item(strPK_KEY_COMBINED)

                Else
                    ret = New T
                End If 'Me
            End If 'ur_key

            SelKey = ret
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelOnKey(ParamArray ur_key() As String) As TablePKStr(Of E, T)
            Dim ret = Me
            For KEYCTR = 1 To Me.PK.Count
                ret = ret.Sel(Me.PK.Item(b0(KEYCTR)), ur_key(b0(KEYCTR)))
            Next

            SelOnKey = ret
        End Function 'SelOnKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                ret = Me.ttb.Item(strPK_KEY_COMBINED)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(strPK_KEY_COMBINED, ret)
            End If

            UseKey = ret
        End Function 'UseKey

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Assign_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T, ur_key() As String)
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                For KEYCTR = 1 To intPK_KEYS
                    ur_row.v(ur_table.PK.Item(b0(KEYCTR))) = ur_key(b0(KEYCTR))
                Next
            End Sub 'Assign_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_key() As String) As String
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To intPK_KEYS
                    If KEYCTR = 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_key(b0(KEYCTR)).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T) As String
                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To ur_table.PK.Count
                    If KEYCTR > 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_row.v_b1(KEYCTR).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKStr


    Partial Public Class Have
        Partial Private Class prv_sample
            Private Class Have
                Private Shared tblUserBowl As sUserBowl

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Sub Connect()
                    If Have.tblUserBowl Is Nothing Then
                        Have.tblUserBowl = New sUserBowl
                    End If 'sdaTCOL_NAME
                End Sub 'Connect

                Public Class enmUB
                    Inherits bitBASE
                    Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                    Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                End Class

                Public Class enmUN
                    Inherits bitBASE
                    Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p1 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p2 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared to_clipboard As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                End Class

                'Public Shared Function UserBowl() As sUserBowl
                '    Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
                '    Call Have.Connect()
                '    UserBowl = Have.tblUserBowl
                '    If bolFIRST_INIT Then
                '        Call Have.tblUserBowl.InsFrom_Application()
                '        Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                '        Call Have.tblUserBowl.Cboard_CmdlineAudit()
                '    End If
                'End Function 'UserBowl

                Public Class rUserBowl
                    Inherits TRow(Of enmUB)

                    <System.Diagnostics.DebuggerHidden()>
                    Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                        vt = Me
                        Me.v(ur_enm) = ur_val
                    End Function

                    'Public Shadows Function Link_Table(ur_child_table As Have.sReport_Detl, ParamArray ur_key_list() As bitRP) As sReport_Detl
                    '    Dim tblRET = New sReport_Detl
                    '    Link_Table = tblRET
                    '    Dim sdpXLAT = New SdPair(Of bitRT)
                    '    Dim stpKEY_BINDINGS = Strapd()
                    '    For Each keyRP In ur_key_list
                    '        stpKEY_BINDINGS.dS(keyRP.name)
                    '        For Each keyRT In ur_child_table.SelFirst.RefColKeys
                    '            If AreEqual(keyRT.name, keyRP.name) Then
                    '                sdpXLAT.d(keyRP.name, keyRT)
                    '            End If
                    '        Next keyRT
                    '    Next keyRP

                    '    If sdpXLAT.Count <> ur_key_list.Length Then
                    '        Throw New System.Exception("Key bindings not found for RT/RP join: " & stpKEY_BINDINGS.ToString)

                    '    Else
                    '        For Each trwJOIN In ur_child_table.SelAll
                    '            Dim bolFOUND = True
                    '            For Each keyRP In ur_key_list
                    '                Dim keyRT = sdpXLAT.l(keyRP.name)
                    '                If AreEqual(trwJOIN.v(keyRT), Me.v(keyRP)) = False Then
                    '                    bolFOUND = False
                    '                    Exit For
                    '                End If
                    '            Next keyRP

                    '            If bolFOUND Then
                    '                tblRET.Ins(trwJOIN)
                    '            End If
                    '        Next trwJOIN
                    '    End If 'sdpXLAT
                    'End Function 'Link_Table
                End Class 'rUserBowl

                Public Class sUserBowl
                    Inherits TablePKEnum(Of enmUB, enmUN, rUserBowl)

                    'Public Sub Cboard_CmdlineAudit()
                    '    If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    '        Dim strAUDIT = Me.ToString(True)
                    '        Dim ins_msg = Mx.Have.MessageBox.Ins(
                    '            New Mx.Have.rMessageBox().
                    '                vt(enmMB.title, Me.SelKey(enmUN.app_name).v(enmUB.contents)).
                    '                vt(enmMB.text, strAUDIT),
                    '            MsgBoxStyle.OkCancel
                    '            )
                    '        If ins_msg.vUserResponse = MsgBoxResult.Ok Then
                    '            Mx.Have.Clipboard.Ins(
                    '                New Mx.Have.rClipboard().
                    '                vt(enmCB.text, strAUDIT)
                    '                )
                    '        End If
                    '    End If
                    'End Sub 'Cboard_CmdlineAudit

                    'Public Function InsFrom_Application() As rUserBowl
                    '    Dim ret = New rUserBowl
                    '    InsFrom_Application = ret
                    '    'Me.InsKey(enmUN.app_name, New MxText.FileName().d(Mx.Class1.SourcePath).FileGroup)
                    '    'Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                    '    'Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                    '    Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                    '    Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                    '    Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                    '    For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    '        Me.Ins(
                    '            New Have.rUserBowl().
                    '            vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                    '            vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                    '            )
                    '    Next
                    'End Function 'InsFrom_Application

                    'Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    '    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                    'End Function
                End Class 'sUserBowl
            End Class 'Have
        End Class 'prv_sample
    End Class 'Have.prv_sample
End Namespace 'Mx

VBNetProject\VBNetScript

VBCode WindowsOS

VBNetScript.EXE

->

VBNetScript.SLN

->


VBNS Project

DOC

  1. ~MockTestReport
  2. ~VersionUpd
  3. Roman to Decimal
  4. Wiki_Move_HTM


VBNS Project\~MockTestReport

ErrorHandling Extract VBCode
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
dbUserInputMock.vb
ScriptRun.vb
subs.vb
RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx2

Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock

    Public Class Want
        Public Shared Function CompileCode_Report_errhnd(ur_commandline_text As String) As Mx.Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Mx.Strapd()
            CompileCode_Report_errhnd = stpRET
            stpRET.d("RED").dLine()
            Dim objERR_LIST = New Mx.ErrListBase : Try
                Call Assistant.CompileCode_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'CompileCode_Report_errhnd
    End Class 'Want

    Public Class Assistant
        Public Shared Sub CompileCode_Report(ur_ret As Mx.Strap)
            Dim windowsfs_env = Have.WindowsFS
            Dim userbowl_cart = Have.UserBowl
            Dim appfolder_bowlname = enmUN.app_folder
            Dim mocktest_cart = Have.MockTest
            Dim intRECS_INSERTED = mocktest_cart.Apply(userbowl_cart, appfolder_bowlname, windowsfs_env)
            Dim intRECS_TESTED = mocktest_cart.Apply(windowsfs_env)

            Dim from_messagebox_bowlname = userbowl_cart.Apply(mocktest_cart, ur_ret)
        End Sub 'CompileCode_Report
    End Class 'Assistant

    Partial Public Class Have
        Partial Public Class sMockTest
            Public Function Apply(ur_userbowl_cart As Have.sUserBowl, ur_appfolder_bowlname As enmUN, ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_ADDED = 0
                Dim strSEARCH_TEST_NAME = "MockTest\*.mock_commandline.txt"
                Dim strSEARCH_RESULT_NAME = ".mock_expect.txt"
                Dim flnAPP_FOLDER = Mx.FileNamed.d(ur_userbowl_cart.SelKey(ur_appfolder_bowlname).Contents)
				Dim fltSEARCH_MOCK_COMMANDLINE = flnAPP_FOLDER.gCopy.d(strSEARCH_TEST_NAME)
                For Each strPATH In ur_windowsfs_env.GetFiles(fltSEARCH_MOCK_COMMANDLINE.gParentDir, fltSEARCH_MOCK_COMMANDLINE.Name, System.IO.SearchOption.TopDirectoryOnly)
					
                    Dim flnTEST_FILE_PATH = Mx.FileNamed.d(strPATH)
                    Dim rowMOCK_TEST = Me.InsKey(strPATH)
                    retREC_ADDED += 1
                    Dim flnTEST_CODE_PATH = flnTEST_FILE_PATH.gParentDir.d(Mx.FileNamed().d(flnTEST_FILE_PATH.FileGroup).FileGroup)
                    For Each strTEST_CODE_PATH In ur_windowsfs_env.GetFiles(flnTEST_CODE_PATH.gParentDir, flnTEST_CODE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.test_code_file, strTEST_CODE_PATH)
                        Exit For
                    Next
					
                    Dim flnRESULT_FILE_PATH = flnTEST_CODE_PATH.gCopy.dAppendEXT(strSEARCH_RESULT_NAME)
                    For Each strEXPECTED_RESULT_PATH In ur_windowsfs_env.GetFiles(flnRESULT_FILE_PATH.gParentDir, flnRESULT_FILE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.mock_expect_file, strEXPECTED_RESULT_PATH)
                        Exit For
                    Next
                Next strPATH

                Apply = retREC_ADDED
            End Function 'Apply ur_userbowl_cart

            Public Function Apply(ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_TESTED = 0
                For Each rowMOCK_TEST In Me.SelAll
                    retREC_TESTED += 1
                    If Mx.HasText(rowMOCK_TEST.v(enmMT.test_code_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Test Code File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    ElseIf Mx.HasText(rowMOCK_TEST.v(enmMT.mock_expect_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Mock Expect File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    Else
						Dim strTEST_CODEFILE_PATH = rowMOCK_TEST.v(enmMT.test_code_file)
                        Dim strCOMMANDLINE_PARMS = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_commandline_file))
                        Dim strEXPECTED_RESULT = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_expect_file))

                        Dim mockTextBox = New Mock.TextBox
                        Dim mockForm = New Mock.Form
                        Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
                        Dim stpTEST_COMMANDLINE = Mx.Strapd().d("vbnetscript.exe").dS("/path=").dSprtr(Mx.qs, strTEST_CODEFILE_PATH).d(Mx.qs).dS(strCOMMANDLINE_PARMS)
                        Call Mx.Want.Compile_And_Run_Script_errhnd(mockUserInput, stpTEST_COMMANDLINE)
                        Dim strFOUND_RESULT = mockTextBox.Text
                        If strFOUND_RESULT = strEXPECTED_RESULT Then
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "1")
						
                        Else
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
                            rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`"))
                        End If 'strFOUND_RESULT
                    End If
                Next rowMOCK_TEST

                Apply = retREC_TESTED
            End Function 'Apply ur_windowsfs_env
        End Class 'sMockTest

        Partial Public Class sUserBowl
            Public Function Apply(ur_mocktest_cart As Have.sMockTest, ur_ret As Mx.Strap) As enmUN
                Dim retUN = enmUN.from_messagebox
                Apply = retUN

                Dim intTEST_PASS = 0
                Dim intTEST_FAIL = 0
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "1" Then
                        intTEST_PASS += 1

                    Else
                        intTEST_FAIL += 1
                    End If
                Next rowMOCK_TEST

                If intTEST_PASS = ur_mocktest_cart.SelAll.Count Then
                    ur_ret.Clear().dLine("GREEN").dLine()
                End If

                ur_ret.dLine(intTEST_PASS.ToString).dS("Tests passed")
                ur_ret.dLine(intTEST_FAIL.ToString).dS("Tests failed")
				ur_ret.dLine()
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "0" Then
                        ur_ret.dLine(rowMOCK_TEST.v(enmMT.test_result_text))
						ur_ret.dLine()
                    End If
                Next rowMOCK_TEST
            End Function 'Apply ur_messagebox_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblMockTest As sMockTest
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblMockTest = New sMockTest
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmMT
        Inherits Mx.bitBASE
        Public Shared mock_commandline_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared mock_expect_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_code_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_result_text As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_pass_count As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
    End Class 'enmMT

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function MockTest() As sMockTest
            Call Have.Connect()
            MockTest = Have.tblMockTest
        End Function

        Public Class rMockTest
            Inherits Mx.TRow(Of enmMT)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmMT, ur_val As String) As rMockTest
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rMockTest

        Public Class sMockTest
            Inherits Mx.TablePKStr(Of enmMT, rMockTest)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                MyBase.New(1)
            End Sub
        End Class
    End Class 'enmMT

    Public Class enmUB
        Inherits Mx.bitBASE
        Public Shared bowl_name As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits Mx.bitBASE
        Public Shared app_folder As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits Mx.bitBASE
        Public Shared Ok As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits Mx.TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = Mx.AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If Mx.HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = Mx.MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = Mx.qs & Have.CmdLineText.Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                Me.SelKey(enmUN.cmdline_table).Contents = Mx.qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx2

VBNS Project\~VersionUpd

AssignVariable Filter VBCode
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.FileUpdate_Report_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.FileUpdate_Report_errhnd
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub FileUpdate_Report(ur_ret As Strap)
            Dim userbowl_cart = Have.UserBowl
            Dim appname_bowlname = enmUN.app_name
            Dim appfolder_bowlname = enmUN.app_folder
            Dim windows_msgbox_env = Have.WindowsMsgBox
            Dim windows_fs_env = Have.WindowsFS
            Dim tempfile_cart = Have.TempFile
            tempfile_cart.Apply(userbowl_cart.SelKey(appfolder_bowlname), windows_fs_env)
            Dim report_output_bowlname = userbowl_cart.Apply(tempfile_cart)
            Dim from_messagebox_bowlname = userbowl_cart.Apply(
                ur_userbowl_text:=userbowl_cart.SelKey(report_output_bowlname),
                ur_userbowl_appname:=userbowl_cart.SelKey(appname_bowlname),
                ur_messagebox_env:=windows_msgbox_env
                )
        End Sub 'FileUpdate_Report

        Public Shared Function FileUpdate_Report_errhnd() As Strap
            Dim stpRET = Strapd()
            FileUpdate_Report_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call FileUpdate_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'FileUpdate_Report_errhnd
    End Class 'Want

    Partial Public Class Have
        Partial Class sTempFile
            Public Sub Apply(ur_app_folder As Have.rUserBowl, ur_windows_fs_env As Have.glblWindowsFS)
                Dim flnROOT_FOLDER = FileNamed().d(ur_app_folder.v(enmUB.contents))
                Dim flnMY_PROJECT = flnROOT_FOLDER.gCopy.d("My Project")
                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnROOT_FOLDER, "*.vbproj", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.VBProj, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.VBProj).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.VBProj.name).dS("file in folder"))
                End If

                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnMY_PROJECT, "AssemblyInfo.vb", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.AssemblyInfo, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.AssemblyInfo).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.AssemblyInfo.name).dS("file in folder"))
                End If
            End Sub 'Apply(ur_app_folder
        End Class 'sTempFile

        Partial Public Class sUserBowl
            Public Function Apply(ur_userbowl_text As Have.rUserBowl, ur_userbowl_appname As Have.rUserBowl, ur_messagebox_env As Have.glblWindowsMsgBox) As bitBASE
                Dim retUN = enmUN.from_messagebox
                Apply = retUN
                Dim enrUSER_INPUT = ur_messagebox_env.GetResult(
                    ur_message:=ur_userbowl_text.v(enmUB.contents),
                    ur_title:=ur_userbowl_appname.v(enmUB.contents),
                    ur_style:=MsgBoxStyle.OkOnly
                    )

                If enrUSER_INPUT = MsgBoxResult.Ok Then
                    Me.InsKey(retUN, enmUR.Ok)
                End If
            End Function 'Apply ur_messagebox_cart

            Public Function Apply(ur_tempfile_cart As Have.sTempFile) As enmUN
                Dim retUN = enmUN.report_output
                Apply = retUN
                Dim strDATE = Today.ToString("yyyy.MM.dd")
                Dim intCURRENT = 1

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.VBProj.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<ApplicationRevision>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationRevision>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, InStr(strPARSE, "<") - 1)
                                    If System.Int32.TryParse(strPARSE, intCURRENT) Then
                                        intCURRENT += 1
                                    End If

                                ElseIf StartingWithText(strLINE.TrimStart, "<ApplicationVersion>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationVersion>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, 10)
                                    If AreEqual(strPARSE, strDATE) = False Then
                                        intCURRENT = 1
                                    End If 'strPARSE

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationRevision>")
                                    stmSECOND.Write(intCURRENT)
                                    stmSECOND.WriteLine("</ApplicationRevision>")

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationVersion>")
                                    stmSECOND.Write(Strapd().d(strDATE).d(intCURRENT.ToString("00")).d(".%2a"))
                                    stmSECOND.WriteLine("</ApplicationVersion>")

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.AssemblyInfo.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyVersion(") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyVersion").d("(").d(qs).d(Today.ToString("yyyy.MM.dd")).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                ElseIf StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyFileVersion") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyFileVersion").d("(").d(qs).d(strDATE).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                Me.InsKey(retUN, Strapd().d("Files updated:").dS(ur_tempfile_cart.SelAll.Count.ToString))
            End Function 'Apply ur_tempfield_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblTempFile As sTempFile
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblTempFile = New sTempFile
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmTF
        Inherits bitBASE
        Public Shared file_search As enmTF = TRow(Of enmTF).glbl.NewBitBase()
        Public Shared filename As enmTF = TRow(Of enmTF).glbl.NewBitBase()
    End Class

    Public Class enmTN
        Inherits bitBASE
        Public Shared AssemblyInfo As enmTN = TRow(Of enmTN).glbl.NewBitBase()
        Public Shared VBProj As enmTN = TRow(Of enmTN).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function TempFile() As sTempFile
            Call Have.Connect()
            TempFile = Have.tblTempFile
        End Function

        Public Class rTempFile
            Inherits TRow(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmTF, ur_val As String) As rTempFile
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rTempFile

        Public Class sTempFile
            Private ttb As Objlist(Of rTempFile)
            Private PK As Objlist(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rTempFile)
                Me.PK = New Objlist(Of enmTF)
                Me.PK.Add(enmTF.file_search)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Del(ur_col As enmTF, ur_val As String)
                For ROWCTR = Me.ttb.Count To 1 Step -1
                    If AreEqual(Me.ttb.tr_b1(ROWCTR).v(ur_col), ur_val) Then
                        Me.ttb.RemoveAt(b0(ROWCTR))
                    End If
                Next ROWCTR
            End Sub 'Del

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Ins(ur_from As rTempFile)
                Dim ttbSEL = Me
                Dim stpPK_LIST = Strapd()
                For Each keyPK In Me.PK
                    Dim strCUR_KEY = ur_from.v(keyPK)
                    If stpPK_LIST.Length > 0 Then stpPK_LIST.d(", ")
                    stpPK_LIST.d(strCUR_KEY)
                    If HasText(strCUR_KEY) = False Then
                        Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("PK value must have data:").dS(keyPK.name))
                    Else
                        ttbSEL = ttbSEL.Sel(keyPK, ur_from.v(keyPK))
                    End If
                Next keyPK

                If ttbSEL.SelAll.Count > 0 Then
                    Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("must have unique PK values:").dS(stpPK_LIST.ToString))
                Else
                    Me.ttb.Add(ur_from)
                End If
            End Sub 'Ins

            <System.Diagnostics.DebuggerHidden()>
            Public Sub InsKey(ur_key As enmTN, ur_val As String)
                Dim ret = Me.SelKey(ur_key)
                If HasText(ret.v(enmTF.filename)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmTF.filename, ur_val)
                End If
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmTF, ur_value As String) As sTempFile
                Dim retUB = New sTempFile
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rTempFile)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmTN) As rTempFile
                Dim ret As rTempFile = Nothing
                Dim strKEY = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmTF.file_search), strKEY) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rTempFile
                    Me.ttb.Add(
                        ret.
                        vt(enmTF.file_search, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sTempFile
    End Class 'TF

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Private ttb As Objlist(Of rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rUserBowl)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rUserBowl) As rUserBowl
                Ins = ur_from
                Me.ttb.Add(ur_from)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As String) As rUserBowl
                Dim ret = Me.SelKey(ur_key)
                InsKey = ret
                If HasText(ret.v(enmUB.contents)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmUB.contents, ur_val)
                End If
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As enmUR) As rUserBowl
                InsKey = Me.InsKey(ur_key, ur_val.name)
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.InsKey(enmUN.app_name, FileNamed().d(Mx.Class1.SourcePath).FileGroup)
                Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmUB, ur_value As String) As sUserBowl
                Dim retUB = New sUserBowl
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rUserBowl)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmUN) As rUserBowl
                Dim ret As rUserBowl = Nothing
                Dim strUN = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmUB.bowl_name), strUN) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rUserBowl
                    Me.ttb.Add(
                        ret.
                        vt(enmUB.bowl_name, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

VBNS Project\Roman to Decimal

Extract Numbers VBCode

Roman to Decimal ZIP

->

  • Asks for a Roman Numeral
  • Returns a decimal number or an error with the invalid sequence and the broken rule
Namespace Mx
	Public Class mb
		Public Shared FirstExec As Object
		Public Shared uinput As Microsoft.VisualBasic.MsgBoxResult

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub ask(ur_text As String)
			Call prv.Connect()
			If mb.uinput <> MsgBoxResult.Cancel Then
				mb.uinput = Microsoft.VisualBasic.MsgBox(ur_text, MsgBoxStyle.OkCancel, "")
			End If
		End Sub 'ask

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Function GetText(ur_question As String) As String
			GetText = Microsoft.VisualBasic.InputBox(ur_question, "")
		End Function

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub reset()
			Call prv.Connect()
			mb.uinput = MsgBoxResult.Ok
		End Sub

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Sub Connect()
				If mb.FirstExec Is Nothing Then
					mb.uinput = MsgBoxResult.Ok
					mb.FirstExec = "done"
				End If
			End Sub 'Connect
		End Class 'prv
	End Class 'mb

	Public Class UserAction
		Public Shared Function Roman_Numeral_Conversion_Report() As String
			mb.reset()
			Dim strRET_MSG = ""
			Dim strNUMERAL = mb.GetText("Enter a Roman numeral")
			Dim strDECIMAL = Assistant.Roman_Numeral_Conversion_Result(strNUMERAL)
			strRET_MSG = strNUMERAL & " rom. = " & strDECIMAL & " dec."
			Roman_Numeral_Conversion_Report = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Report
	End Class 'UserAction

	Public Class Assistant
		Public Shared Function Roman_Numeral_Conversion_Result(ur_numeral As String) As String
			Dim strRET_MSG = ""
			Dim rmnNUMERAL = New Mx.glblRomanNumeral(ur_numeral)
			strRET_MSG = rmnNUMERAL.Validation_Message
			If strRET_MSG = "" Then
				strRET_MSG = rmnNUMERAL.ToInteger.ToString
			End If

			Roman_Numeral_Conversion_Result = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Result
	End Class 'Assistant

	Public Class glblRomanNumeral
		Private strpNumeral As String

		Private Enum enmLH
			low_or_high_number
			high_number
			low_number
		End Enum

		Private siaSymbol_Size As Mx.sia

		<System.Diagnostics.DebuggerHidden()>
		Public Sub New(ur_numeral As String)
			Me.strpNumeral = ur_numeral.Trim.ToUpper
			Me.siaSymbol_Size = prv.glbl_Symbol_Sizes()
		End Sub

		Public ReadOnly Property Numeral As String
			<System.Diagnostics.DebuggerHidden()>
			Get
				Numeral = Me.strpNumeral
			End Get
		End Property 'Numeral

		Public Function IsValid() As Boolean
			IsValid = (Me.Validation_Message = "")
		End Function

		Public Function Validation_Message() As String
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_Valid

			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, "", symbol_size_table)

			Validation_Message = clrRET_STATE.strNOTICE_MSG
		End Function 'Validation_Message

		Public Function ToInteger() As Integer
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_State
			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				Dim clPREV_STATE = clrRET_STATE
				clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, "", symbol_size_table)

			ToInteger = clrRET_STATE.intRET_NUM
		End Function 'ToInteger

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function glbl_Symbol_Sizes() As Mx.sia
				Dim retSIA = New Mx.sia
				glbl_Symbol_Sizes = retSIA
				retSIA.Add("I", 1)
				retSIA.Add("V", 5)
				retSIA.Add("X", 10)
				retSIA.Add("L", 50)
				retSIA.Add("C", 100)
				retSIA.Add("D", 500)
				retSIA.Add("M", 1000)

				glbl_Symbol_Sizes = retSIA
			End Function 'glbl_Symbol_Sizes

			Public Class Loop_State
				Public enrSTATE As enmLH
				Public strLOW_OR_HIGH_TEMP As String
				Public intRET_NUM As Integer

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Me.enrSTATE = enmLH.high_number
					Me.strLOW_OR_HIGH_TEMP = ""
					Me.intRET_NUM = 0
				End Sub 'New
			End Class 'Loop_State

			Public Class Loop_Valid
				Public strVAL_FOUR As String
				Public strVAL_THREE As String
				Public strVAL_TWO As String
				Public strVAL_ONE As String
				Public intVAL_FOUR As Integer
				Public intVAL_THREE As Integer
				Public intVAL_TWO As Integer
				Public intVAL_ONE As Integer
				Public strNOTICE_MSG As String

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Call prvLoop_Valid.Reset_Symobls(Me)
					Me.strNOTICE_MSG = ""
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia)
					Me.strVAL_FOUR = ur_state.strVAL_THREE
					Me.intVAL_FOUR = ur_state.intVAL_THREE
					Me.strVAL_THREE = ur_state.strVAL_TWO
					Me.intVAL_THREE = ur_state.intVAL_TWO
					Me.strVAL_TWO = ur_state.strVAL_ONE
					Me.intVAL_TWO = ur_state.intVAL_ONE
					Me.strVAL_ONE = ur_new_symbol
					Me.intVAL_ONE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
					Me.strNOTICE_MSG = ur_state.strNOTICE_MSG
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub Assign_NoticeMsg(ur_message As String)
					If strNOTICE_MSG <> "" Then
						strNOTICE_MSG &= vbCrLf & vbCrLf
					End If

					strNOTICE_MSG &= ur_message
					Call prvLoop_Valid.Reset_Symobls(Me)
				End Sub 'Assign_NoticeMsg

				Private Class prvLoop_Valid
					Public Shared Sub Reset_Symobls(ur_state As prv.Loop_Valid)
						ur_state.strVAL_FOUR = ""
						ur_state.intVAL_FOUR = 0
						ur_state.strVAL_THREE = ""
						ur_state.intVAL_THREE = 0
						ur_state.strVAL_TWO = ""
						ur_state.intVAL_TWO = 0
						ur_state.strVAL_ONE = ""
						ur_state.intVAL_ONE = 0
					End Sub 'Reset_Symobls
				End Class 'prv
			End Class 'Loop_Valid

			Public Shared Function Loop_Return_Valid(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_Valid
				Dim retSTATE = New prv.Loop_Valid(ur_state, ur_new_symbol, ur_symbol_size)
				Loop_Return_Valid = retSTATE
				If retSTATE.strVAL_ONE <> "" Then
					If retSTATE.intVAL_ONE = 0 Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							If strLIST <> "" Then
								strLIST &= ", "
							End If

							strLIST &= strENTRY
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used in Roman numerals.")

					ElseIf retSTATE.strVAL_FOUR = retSTATE.strVAL_THREE AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_TWO AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_ONE Then
						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_FOUR & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & ur_new_symbol & "] is not valid: A single symbol may not be repeated more than three times.")

					ElseIf retSTATE.strVAL_TWO = retSTATE.strVAL_ONE AndAlso
					  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
							If Left(strENTRY_VAL, 1) = "1" Then
								If strLIST <> "" Then
									strLIST &= ", "
								End If

								strLIST &= strENTRY
							End If
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be repeated.")

					ElseIf retSTATE.strVAL_TWO <> "" Then
						If retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
							Dim strLIST = ""
							For Each strENTRY In ur_symbol_size.Keys
								Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
								If Left(strENTRY_VAL, 1) = "1" Then
									If strLIST <> "" Then
										strLIST &= ", "
									End If

									strLIST &= strENTRY
								End If
							Next strENTRY

							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used as the lower symbol followed by a higher symbol.")

						ElseIf retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  retSTATE.intVAL_ONE <> retSTATE.intVAL_TWO * 10 Then
							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: The lower symbol must be ten times less value than the following higher symbol.")

						ElseIf retSTATE.strVAL_THREE <> "" Then
							If retSTATE.intVAL_TWO > retSTATE.intVAL_ONE AndAlso
							  retSTATE.intVAL_ONE >= retSTATE.intVAL_THREE Then
								retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: A lower symbol followed by higher symbol must be followed by lower symbol than the first of the series.")
							End If
						End If 'strVAL_THREE
					End If 'strVAL_TWO
				End If 'strVAL_ONE
			End Function 'Loop_Return_Valid

			Public Shared Function Loop_Return_State(ur_state As prv.Loop_State, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_State
				Dim retSTATE = New prv.Loop_State
				Loop_Return_State = retSTATE

				Dim intNEW_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
				Dim intLOW_OR_HIGH_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_state.strLOW_OR_HIGH_TEMP)
				If ur_state.strLOW_OR_HIGH_TEMP = "" Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM
					retSTATE.enrSTATE = enmLH.low_or_high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol

				ElseIf intNEW_VALUE > intLOW_OR_HIGH_VALUE Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intNEW_VALUE - intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ""

				Else
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.low_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol
				End If
			End Function 'Loop_Return_State

			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function Numeral_To_Int(ur_symbol_size As Mx.sia, ur_numeral As String) As Integer
				Numeral_To_Int = 0
				If ur_symbol_size.ContainsKey(ur_numeral) Then
					Numeral_To_Int = ur_symbol_size.Item(ur_numeral)
				End If
			End Function 'Numeral_To_Int
		End Class 'prv
	End Class 'glblRomanNumeral

	Public Class sia
		Inherits System.Collections.Generic.Dictionary(Of String, Integer)
	End Class
End Namespace 'Mx

VBNS Project\Wiki_Move_HTM

Filter TWCard VBCode

Wiki Move HTM

->

@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
End Function '2021m01d03
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Const strLIT_WIKI_MOVE_5_SEC = "Wiki Move 5-Sec"
        Const strvLIT_USER_PROFILE_DOWNLOADS = "%USERPROFILE%\downloads"
        Const strLIT_STAR_DOT_HTM = "WikiMove_*-stamp-*.htm"
        Const strLIT_STAR_DOT_HTML = "WikiMove_*-stamp-*.html"
        Const strLIT_STAR_DOT_CARDTXT = "WikiMove_*-stamp-*.card*.txt"

        Public Shared Sub UITimer_to_Poll_FileDir_And_Move(ur_ret As Strap)
            ur_ret.d("QUIT")
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            Dim strUI_FORM_TITLE = strLIT_WIKI_MOVE_5_SEC
            userbowl_cart.SelKey(uiform_title_bowlname).Contents = strUI_FORM_TITLE
            userbowl_cart.SelKey(enmUN.poll_folder).Contents = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)
            If glbl.gDiagnostics.IsRunningWindow(strUI_FORM_TITLE) Then
                glbl.gInteraction.AppActivate(strUI_FORM_TITLE)

            Else
                Dim objFORM = New Mx.WikiMove_Form()
                objFORM.Text = userbowl_cart.SelKey(enmUN.uiform_title).v(enmUB.contents)
                Call objFORM.Display_FolderList()
                objFORM.tmrFIVE_SEC.Start()
                Dim strNEW_DATA_FOLDER = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)

                'System.Windows.Forms.Application.Run(objFORM) only works from a command line program with no forms open. VBNetScript already has a form open.
                Call objFORM.ShowDialog()
            End If 'gDiagnostics
        End Sub 'UITimer_to_Poll_FileDir_And_Move

        Public Shared Function UITimer_to_Poll_FileDir_And_Move_errhnd(ur_commandline_text As String) As Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Strapd()
            UITimer_to_Poll_FileDir_And_Move_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call UITimer_to_Poll_FileDir_And_Move(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'UITimer_to_Poll_FileDir_And_Move_errhnd

        Public Shared Sub Poll_FileDir_And_Move(ur_ui_form As WikiMove_Form)
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            Dim windows_fs_cart = Have.WindowsFS
            Dim filemove_cart = Have.FileMove
            Call ur_ui_form.Display_FolderList()
            filemove_cart.DelAll()
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTM)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTML)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_CARDTXT)
            filemove_cart.Move_Files()
            Dim report_output_bowlname = userbowl_cart.Apply(filemove_cart)
            Dim strREPORT_OUTPUT = userbowl_cart.SelKey(report_output_bowlname).v(enmUB.contents)
            If HasText(strREPORT_OUTPUT) Then
                ur_ui_form.txtOUTPUT.Text = strREPORT_OUTPUT & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move

        Public Shared Sub Poll_FileDir_And_Move_errhnd(ur_ui_form As WikiMove_Form)
            Dim objERR_LIST = New ErrListBase : Try
                Call Poll_FileDir_And_Move(ur_ui_form:=ur_ui_form)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                ur_ui_form.txtOUTPUT.Text = objERR_LIST.ToString & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move_errhnd

        Public Class CombineTextOutput
            Public gText As Strap
            Public gFolderList As Sdata

            Public Sub New(ur_text As Strap, ur_folder_list As Sdata)
                Me.gText = ur_text
                Me.gFolderList = ur_folder_list
            End Sub
        End Class 'CombineTextOutput
    End Class 'sub_main

    Public Class WikiMove_Form
        Inherits System.Windows.Forms.Form

        Public tmrFIVE_SEC As System.Windows.Forms.Timer
        Public txtOUTPUT As System.Windows.Forms.TextBox
        Public intSHOW_FORM As Integer

        Public Sub New()
            Me.intSHOW_FORM = 1

            Me.Name = "Wiki_Move"
            Me.Size = New System.Drawing.Size(400, 400)
            Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen

            Me.txtOUTPUT = New System.Windows.Forms.TextBox()
            Me.txtOUTPUT.Name = "txtOUTPUT"
            Me.txtOUTPUT.Multiline = True
            Me.txtOUTPUT.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
            Me.txtOUTPUT.Dock = System.Windows.Forms.DockStyle.Fill
            Me.Controls.Add(Me.txtOUTPUT)

            Me.tmrFIVE_SEC = New System.Windows.Forms.Timer()
            Me.tmrFIVE_SEC.Interval = 50
            AddHandler Me.tmrFIVE_SEC.Tick, AddressOf Timer1_Tick
        End Sub 'New

        Sub Display_FolderList()
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            If HasText(Me.txtOUTPUT.Text) = False Then
                Me.txtOUTPUT.Text = Strapd().dLine("Listening:").dS(userbowl_cart.SelKey(pollfolder_bowlname).v(enmUB.contents)).dLine().d(Me.txtOUTPUT.Text)
            End If
        End Sub 'Display_FolderList

        Sub Look_For_Files()
            Call Mx.Want.Poll_FileDir_And_Move_errhnd(Me)
        End Sub

        Sub Show_Saved()
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            If Me.intSHOW_FORM = 1 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Normal
                Call AppActivate(userbowl_cart.SelKey(uiform_title_bowlname).v(enmUB.contents))
                Me.tmrFIVE_SEC.Interval = 800
                Me.intSHOW_FORM = 2

            ElseIf Me.intSHOW_FORM = 2 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Minimized
                Me.intSHOW_FORM = 0

            ElseIf Me.intSHOW_FORM = 0 Then
                If Me.WindowState <> System.Windows.Forms.FormWindowState.Minimized Then
                    Me.intSHOW_FORM = 6
                End If

            Else
                Me.intSHOW_FORM -= 1
            End If
        End Sub 'Show_Saved

        Sub Timer1_Tick(sender As Object, e As System.EventArgs)
            Me.tmrFIVE_SEC.Stop()
            Me.tmrFIVE_SEC.Interval = 5000
            Call Look_For_Files()
            Call Show_Saved()
            Me.tmrFIVE_SEC.Start()
        End Sub 'Timer1_Tick
    End Class 'WikiMove_Form




    Public Class Have
        Partial Class sFileMove
            Public Sub Apply(ur_windows_fs_cart As Have.glblWindowsFS, ur_userbowl_cart As Have.sUserBowl, ur_poll_folder_bowlname As enmUN, ur_filespec As String)
                Dim strPOLL_FOLDER = ur_userbowl_cart.SelKey(ur_poll_folder_bowlname).Contents
                For Each strFILE_PATH In ur_windows_fs_cart.GetFiles(strPOLL_FOLDER, ur_filespec, System.IO.SearchOption.TopDirectoryOnly)
                    Dim flnFILE_NAME = FileNamed().d(strFILE_PATH)
                    Dim sdaEXT_LIST = flnFILE_NAME.ExtList
                    Dim strDEST_PATH_ENCODED_IN_NAME = flnFILE_NAME.Name.Substring("WikiMove_".Length)
                    Dim strDEST_PATH = strDEST_PATH_ENCODED_IN_NAME.Replace("-colon-", ":").Replace("-fslash-", "\")
                    Dim intSTAMP = InStr(strDEST_PATH, "-stamp-")
                    strDEST_PATH = Left(strDEST_PATH, intSTAMP - 1)
                    Dim strEXT = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count))
                    If sdaEXT_LIST.Count > 1 Then
                        Dim strEXT2 = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count - 1))
                        If AreEqual(strEXT, ".txt") AndAlso
                          StartingWithText(strEXT2, ".card") Then
                            strEXT = ".card.txt"
                        End If
                    End If 'sdaEXT_LIST

                    strDEST_PATH &= strEXT
                    Me.Ins(
                        New rFileMove().
                        vt(enmFM.src_file_path, strFILE_PATH).
                        vt(enmFM.dest_file_path, strDEST_PATH)
                        )
                Next strFILE_PATH
            End Sub 'Apply ur_windows_fs_cart

            Public Sub Move_Files()
                Dim lstLEN = New System.Collections.Generic.List(Of Integer)
                For Each rowFILE In Me.SelAll
                    Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                    Dim intLEN = strFILE_PATH.Length
                    If lstLEN.Contains(intLEN) = False Then
                        lstLEN.Add(intLEN)
                    End If
                Next rowFILE

                Call lstLEN.Sort()
                For Each intLEN In lstLEN
                    For Each rowFILE In Me.SelAll
                        Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                        If strFILE_PATH.Length = intLEN Then
                            Dim strDEST_PATH = rowFILE.v(enmFM.dest_file_path)
                            glbl.gWindowsFS.Move(strFILE_PATH, strFILE_PATH & ".TDLY")
                            glbl.gWindowsFS.Delete(strDEST_PATH)
                            glbl.gWindowsFS.Move(strFILE_PATH & ".TDLY", strDEST_PATH)
                        End If 'strFILE_PATH
                    Next rowFILE
                Next intLEN
            End Sub 'Move_Files
        End Class 'sFileMove

        Partial Class sUserBowl
            Public Function Apply(ur_filemove_cart As sFileMove) As enmUN.zreport_output
                Dim retKEY = enmUN.report_output
                Apply = retKEY
                Dim stpREPORT = Strapd()
                For Each rowFILE In ur_filemove_cart.SelAll
                    stpREPORT.dLine(Now.ToString("tt hh:mm:ss")).d(":").dS(rowFILE.v(enmFM.dest_file_path))
                Next rowFILE

                Me.SelKey(retKEY).v(enmUB.contents) = stpREPORT
            End Function 'Apply(ur_filemove_cart
        End Class 'sUserBowl
    End Class 'Have



    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblFileMove As sFileMove
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblFileMove = New sFileMove
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmFM
        Inherits bitBASE
        Public Shared src_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
        Public Shared dest_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
    End Class

    Partial Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function FileMove() As sFileMove
            Call Have.Connect()
            FileMove = Have.tblFileMove
        End Function

        Public Class rFileMove
            Inherits TRow(Of enmFM)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmFM, ur_val As String) As rFileMove
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rFileMove

        Public Class sFileMove
            Private ttb As Objlist(Of rFileMove)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rFileMove)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub DelAll()
                Me.ttb.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rFileMove) As rFileMove
                Ins = ur_from
                Dim ttbSEL = Me
                Me.ttb.Add(ur_from)
            End Function 'Ins

            Public ReadOnly Property SelAll() As Objlist(Of rFileMove)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sFileMove
    End Class 'Have

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared poll_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared uiform_title As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function 'UserBowl

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = Have.WindowsMsgBox.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(strAUDIT)
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

View All Cards

$:/positivesigner/text-ref
Recursive transclusion error in transclude widget

View All Code

$:/positivesigner/text-ref


$:/config/MissingLinks

$:/positivesigner/base-install
no

$:/config/Navigation/openLinkFromOutsideRiver

$:/positivesigner/base-install
bottom

$:/config/Navigation/Permalinkview/CopyToClipboard

$:/positivesigner/base-install
no

$:/config/ShortcutInfo/font-large

$:/positivesigner/text-ref

$:/config/ShortcutInfo/font-normal

$:/positivesigner/text-ref

$:/config/ShortcutInfo/home-tiddlers

$:/positivesigner/home-button

$:/config/ShortcutInfo/save-all-changes

$:/positivesigner/base-install

$:/config/shortcuts/font-large

$:/positivesigner/text-ref
ctrl-shift-Quote

$:/config/shortcuts/font-normal

$:/positivesigner/text-ref
ctrl-shift-Comma

$:/config/shortcuts/home-tiddlers

$:/positivesigner/home-button
alt-H

$:/config/shortcuts/save-all-changes

$:/positivesigner/base-install
alt-S

$:/config/TextEditor/EnableToolbar

$:/positivesigner/text-ref
no

$:/config/ViewToolbarButtons/Visibility/$:/positivesigner/gcmpr/btn gcmpr card

$:/positivesigner/gcmpr
hide

$:/config/WikiParserRules/Inline/wikilink

$:/positivesigner/base-install
disable

$:/DefaultTiddlers

$:/positivesigner/base-install
[tag[INDEX]has[sort_ord]sort[title]]
[tag[INDEX]!has[sort_ord]sort[title]]

$:/language/DefaultNewTiddlerTitle

$:/positivesigner/base-install
New Card

$:/positivesigner/base-install

$:/positivesigner/base-install $:/positivesigner/gcmpr $:/positivesigner/home-button $:/positivesigner/text-ref $:/positivesigner/div-pop
\define show_pill()
<<tag-pill tag:"$(cur_entry)$" >>
\end
---
<$list variable=cur_entry filter="[prefix[$:/positivesigner/]is[tag]sort[]]">

<<cur_entry>>
</$list>

$:/positivesigner/div-pop

$:/positivesigner/base-install $:/positivesigner/div-pop

$:/positivesigner/gcmpr

$:/positivesigner/gcmpr $:/positivesigner/base-install

$:/positivesigner/gcmpr/btn gcmpr card

$:/tags/ViewToolbar $:/positivesigner/gcmpr
<<gcmpr_btn_cmp_current>> 

$:/positivesigner/gcmpr/mcr gcmpr_compare_card

$:/tags/Macro $:/positivesigner/gcmpr
\define gcmpr_compare_card(ur_ttb_card)
<$list variable=ttb_card filter="[[$ur_ttb_card$]!match[]]">
<$list variable=compare_card filter="[<ttb_card>addprefix[$:/state/popup/compare-card/]]">
<$link to=<<ttb_card>> />
<<gcmpr_ref_edit_source_text>>
<<gcmpr_ref_copy_over_ttb_card>>
<br>
<$link to=<<compare_card>> />
<<gcmpr_ref_replace_comment_endings>>
<<gcmpr_ref_disp_diff_text>>
<$edit-text autoHeight=no tiddler=<<compare_card>> tag=textarea default="" />
<<gcmpr_ref_disp_textedit_link>>
</$list><!--compare_card-->
</$list><!--ttb_card-->
<!--gcmpr_compare_card-->
\end

\define gcmpr_ref_edit_source_text(ttb_card, compare_card)
<$vars enr_text="text" >
<$list variable=source_text filter="[<ttb_card>get<enr_text>else[]]">
<$button>
<$action-setfield $tiddler=<<compare_card>> text=<<source_text>> />
Copy Source
</$button>
</$list><!--source_text-->
</$vars><!--enr_text-->
<!--gcmpr_ref_edit_source_text-->
\end

\define gcmpr_ref_copy_over_ttb_card(ttb_card, compare_card)
<$vars enr_text="text" >
<$list variable=compare_text filter="[<compare_card>get<enr_text>else[]]">
<$button>
<$action-setfield $tiddler=<<ttb_card>> text=<<compare_text>> />
Overwrite Source
</$button>
</$list><!--compare_text-->
</$vars><!--enr_text-->
<!--gcmpr_ref_copy_over_ttb_card-->
\end

\define gcmpr_ref_replace_comment_endings(ttb_card, compare_card)
<$button>
<$vars comment_flag="--" lit_exclm="!" lit_lt="<" lit_gt=">" enr_text="text" >
<$wikify name=lit_lf text="&#10;">
<$list variable=comment_open_text filter="[<lit_lt>addsuffix<lit_exclm>addsuffix<comment_flag>]">
<$list variable=comment_close_text filter="[<comment_flag>addsuffix<lit_gt>]">
<$list variable=comment_close_replace filter="[<comment_flag>addsuffix<lit_exclm>addsuffix<lit_gt>]">
<$list variable=replace_text filter="[<compare_card>get<enr_text>split<comment_close_text>join<comment_close_replace>addprefix<lit_lf>addprefix<comment_open_text>addsuffix<lit_lf>addsuffix<comment_close_text>]">
<$action-setfield $tiddler=<<compare_card>> text=<<replace_text>> />
</$list><!--replace_text-->
</$list><!--comment_close_replace-->
</$list><!--comment_close_text-->
</$list><!--comment_open_text-->
</$wikify>
</$vars><!--comment_flag, lit_exclm, lit_lt, lit_gt-->
Replace comment endings
</$button><br>
<!--gcmpr_ref_replace_comment_endings-->
\end

\define gcmpr_ref_disp_diff_text()
<$list variable=val_ttb_card filter="[<ttb_card>get[text]!match[]]">
<$list variable=val_compare_card filter="[<compare_card>get[text]!match[]]">
<$diff-text source=<<val_ttb_card>> dest=<<val_compare_card>> />
</$list><!--val_compare_card-->
</$list><!--val_ttb_card-->
<!--gcmpr_ref_disp_diff_text-->
\end

\define gcmpr_ref_disp_textedit_link()
<$list variable=cur_url filter="[{$:/info/url/full}]">
<$list variable=new_link filter="[<cur_url>addsuffix[#]addsuffix[$:/positivesigner/gcmpr/textarea]split[$:]join[%24%3A]]">
<a href=<<new_link>> target="_blank" >text editor</a>
</$list>
</$list>
<!--gcmpr_ref_disp_textedit_link-->
\end

\define gcmpr_btn_cmp_current()
<$list variable=cur_card filter="[all[current]]">
<$list variable=dest_card filter="[<cur_card>addprefix[$:/state/popup/gcmpr/]]">
<$vars lit_lt="<" lit_gt=">" lit_s=" " lit_qs='"' macro_name="gcmpr_compare_card" enr_text="text" >
<$list variable=macro_call_text filter="[<lit_lt>addsuffix<lit_lt>addsuffix<macro_name>addsuffix<lit_s>addsuffix<lit_qs>addsuffix<cur_card>addsuffix<lit_qs>addsuffix<lit_gt>addsuffix<lit_gt>]">
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler=<<dest_card>> text=<<macro_call_text>> />
<$action-navigate $to=<<dest_card>> />
Compare to Textbox
</$button>
</$list><!--macro_call_text-->
</$vars><!--lit_lt-->
</$list><!--dest_card-->
</$list><!--cur_card-->
<!--gcmpr_btn_cmp_current-->
\end

\define gcmpr_textarea_new()
<$vars enr_text="text" enr_new_filename="new_filename" enr_rows="rows" enr_cols="cols" enr_disp_btn_incr_decr="disp_btn_incr_decr" lit_state_popup_prefix="$:/state/popup/gcmpr_textarea/" lit_default_rows="20" lit_default_cols="160" cur_card=<<currentTiddler>> >
<$list variable=temp_card filter="[<cur_card>addprefix<lit_state_popup_prefix>]">
New file name:
@@margin-left:5px;
<$edit-text tiddler=<<temp_card>> field=new_filename placeholder="" autoHeight=yes tag=input/>
@@
<$list variable=val_disp_btn_incr_decr filter="[<temp_card>get<enr_disp_btn_incr_decr>!match[]else[]]">
<$list variable=val_rows filter="[<temp_card>get<enr_rows>!match[]!match[0]else<lit_default_rows>]">
<$list variable=val_cols filter="[<temp_card>get<enr_cols>!match[]!match[0]else<lit_default_cols>]">
<$list variable=val_new_filename filter="[<temp_card>get<enr_new_filename>!match[]]">
<$list variable=new_card filter="[<val_new_filename>addprefix<lit_state_popup_prefix>]">
<$list variable=new_temp_card filter="[<new_card>addprefix<lit_state_popup_prefix>]">
<$list variable=filter_newcard_not_exists filter="[<new_card>!is[tiddler]]">
<$button>
<$list variable=cur_card_text filter="[<cur_card>get<enr_text>]">
<$action-setfield $tiddler=<<new_card>> $field=<<enr_text>> $value=<<cur_card_text>> />
</$list><!--cur_card_text-->
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_new_filename>> $value=<<val_new_filename>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_rows>> $value=<<val_rows>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_cols>> $value=<<val_cols>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_disp_btn_incr_decr>> $value=<<val_disp_btn_incr_decr>> />
<$action-navigate $to=<<new_card>> />
New card
</$button>
</$list><!--filter_newcard_not_exists-->
</$list><!--new_temp_card-->
</$list><!--new_card-->
</$list><!--val_new_filename-->

<br>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>!match[]]">
@@margin-right:20px;
<$button>
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_disp_btn_incr_decr>> $value="" />
Show Resize buttons
</$button>
@@
</$list><!--filter_disp_buttons-->
Rows: <<val_rows>>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>match[]]">
<$button>
<$list variable=val_new_rows filter="[<val_rows>add[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_rows>> $value=<<val_new_rows>> 
/>
</$list><!--val_new_rows-->
+
</$button>
<$list variable=filter_zero_rows filter="[<val_rows>!match[0]]">
<$button>
<$list variable=val_new_rows filter="[<val_rows>subtract[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_rows>> $value=<<val_new_rows>> />
</$list><!--val_new_rows-->
-
</$button>
</$list><!--filter_zero_rows-->
</$list><!--filter_disp_buttons-->
Cols: <<val_cols>>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>match[]]">
<$button>
<$list variable=val_new_cols filter="[<val_cols>add[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_cols>> $value=<<val_new_cols>> />
</$list><!--val_new_cols-->
+
</$button>
<$list variable=filter_zero_cols filter="[<val_cols>!match[0]]">
<$button>
<$list variable=val_new_cols filter="[<val_cols>subtract[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_cols>> $value=<<val_new_cols>> />
</$list><!--val_new_cols-->
-
</$button>
@@margin-left:20px;
<$button>
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_disp_btn_incr_decr>> $value="hide" />
Hide resize buttons
</$button>
@@
</$list><!--filter_disp_buttons-->
</$list><!--filter_zero_cols-->
<br>
<textarea rows=<<val_rows>> cols=<<val_cols>> />
</$list><!--val_cols-->
</$list><!--val_rows-->
</$list><!--val_disp_btn_incr_decr-->
</$list><!--temp_card-->
</$vars><!--enr_new_filename-->
\end

\define glbl_chk(ur_field)
<br><$checkbox tiddler=<<currentTiddler>> field="$ur_field$" unchecked="no" checked="yes"></$checkbox><span style="margin-right:5px;" />
\end

$:/positivesigner/gcmpr/textarea

$:/positivesigner/gcmpr
<<gcmpr_textarea_new>>

$:/positivesigner/home-button

$:/positivesigner/home-button $:/positivesigner/base-install

$:/positivesigner/text-ref

$:/positivesigner/base-install $:/positivesigner/text-ref

$:/themes/tiddlywiki/vanilla/options/sidebarlayout

$:/positivesigner/base-install
fluid-fixed

AndroidChromeBrowser

DOC
<<glbl_article_list>>

AndroidChromeBrowser\Desktop Shortcut to Website

AndroidOS Browser FileSystem
"""
This does not work for file:///sdcard HTML files
Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Google Chrome app]
- [Non-incognito mode]
- Navigate to website page
- Note: This does not work for file:///sdcard HTML files
- [Top-right icons]
- Click the three-lines menu, option Add to Home screen -> Opens dialog
- [Add to Home screen dialog]
- Shortcut name / UrShortcutName
- Click button Add -> Closes dialog

[Desktop icons]
- Click icon UrShortcutName -> Opens browser

AndroidGit

DOC
<<glbl_article_list>>

AndroidGit\Pocket Git pull repository updates

AndroidOS GitCode FileSystem UserAction
"""
[Pocket Git app]
- [Repositories List page, Top-right icons]
- Click button Preferences (looks like three lines) -Navigates page
- [Preferences page, Defaults section]
- Click link Default Directory -> Opens dialog
- [Select Folder dialog]
- Select the Downloads folder -> Closes dialog
- [Preferences page, Defaults section]
- Note: Default Directory = /storage/emulated/0/Download
- Click button Back (looks like a left arrow) -> Navigates page

- [Repositories List page, Bottom-right icons]
- Click button Create Project (looks like a red button with a Plus sign) -> Opens dialog
- [Create Project dialog]
- Project Name = UrProjectName
- Clone URL = UrRepositoryURL
- Note: Local Path automatically creates a sub-directory under the Downloads folder
- Click the Authentication drop-list, option Password
- Username = UrRepositoryUsername
- Password = UrRepositoryPassword
- [Create Project dialog, Top-right icons]
- Click button Save (looks like a floppy disk) -> Closes dialog

- [Repositories List page]
- Click repository UrProjectName -> Navigates page

- [Repository page, Top-right icons]
- Click the Remotes menu (looks like a cloud), click option Fetch -> Starts process
- Wait for popup message "Finished fetching"
- Click the Remotes menu, click option Pull -> Starts process
- Wait for popup message "Finished pulling"

[File system]
- [Downloads folder]
- Note: All the files in the repository are available under the UrProjectName sub-folder in the Downloads folder

AndroidMultipleUsers

DOC
<<glbl_article_list>>

AndroidMultipleUsers\Common access files

AndroidOS FileSystem UserAction
"""
When you change users on an Android device, the file:///sdcard/ folder is aliased to a different location for each. There is a specific sub-folder that is aliased to the same location for all users.

[File Manager]
- Navigate to /sdcard/Android/obb
- Create a folder and copy files into it

[Android Notices menu]
- Change the current user

[File Manager]
- Navigate to /sdcard/Android/obb
- You can see the same folder and files from the other login

AndroidProgramming

DOC
<<glbl_article_list>>

AndroidProgramming\DCoder

AndroidOS VBCode FileSystem
Note: I found that the DCoder app actually submitted the VB code to a web server. So there was no way for me to access the local file system.

```
  'Visual Basic.Net Compiler version 0.0.0.5943 (Mono 4.0.1)

Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Namespace Dcoder
  Public Module Program
    Public Sub Main(args() As string)
      Dim strRET = "Hi"
      For Each strENTRY As String In SubDir_List("/")
          For Each strE2 As String In SubDir_List("/" & strENTRY)
          For Each strE3 As String In SubDir_List("/" & strENTRY)
              strRET &= vbLf & strENTRY & "/" & strE2 & "/" & strE3
          Next strE3
          Next strE2
      Next strENTRY
      
      strRET &= vbLf & "Done"
      Console.WriteLine(strRET)
    End Sub 'Main

    Public Function t1(ur_root_dir As String) As String
        Return "no"
    End Function

    Public Function SubDir_List(ur_root_dir As String) As System.Collections.Generic.List(Of String)
      Dim lstRET = New System.Collections.Generic.List(Of String)
      SubDir_List = lstRET
      Try
      Dim proc = New System.Diagnostics.Process
      Dim stg = new System.Diagnostics.ProcessStartInfo
      proc.StartInfo = stg
      stg.FileName = "ls"
      stg.Arguments = ur_root_dir

      'stg.FileName = "find"
      'stg.Arguments = ". -name '*' -print"

      stg.UseShellExecute = false
      stg.RedirectStandardOutput= true
      stg.RedirectStandardError = true
      stg.CreateNoWindow = true
      proc.Start()
      Dim strCL_OUT = proc.StandardOutput.ReadToEnd()
      'strRET = "[Output: " & vbLf & strCL_OUT & "]"
      'strRET &= vbLf & "(err: " & vbLf & proc.StandardError.ReadToEnd() & ")"
      For Each strENTRY As String In strCL_OUT.Split(CHR(10))
          If strENTRY <> "" Then
              lstRET.Add(strENTRY)
          End If
      Next strENTRY
      Catch ex As System.Exception
      End Try
    End Function 'SubDir_List
  End Module
End Namespace

AndroidQLua

DOC
<<glbl_article_list>>

AndroidQLua\Console Commands

AndroidOS LuaCode CodeLibrary
"""
[QLua app]
- Click button Console -> Navigates page

- [console window]
- Note: The right-arrow symbol (greater-than sign) is the Lua prompt
- Note: Comment line-endings in a Lua file are separated by two hyhpens
"""

```
--Single-line comment
ur_object.ur_function() --Comment until end of line
```

"""
- Note: Multi-line comments in a Lua file are separated by two hyphens and two open brackets, and closed by two hyphens and two close brackets
"""

```
--[[
Block comment
multiple lines
--]]
```

"""
- Note: Commands in Lua are case sensitive
- - You can create functions named `abc`, `Abc`, `abC`, and `ABC`, and each one can store to a different value

- Note: Exiting the Lua interpreter returns to the Linux Shell command line interpreter that was created by QLua
- Run the `os.exit()` command
"""

```
os.exit()
```

"""
[Linux Shell CLI]
- Note: The $ symbol (dollar sign) is the Linux Shell prompt
- Note: Commands in Linux Shell are case sensitive
- - You can create programs named `abc`, `Abc`, `abC`, and `ABC`, and each one can run different code
- - Most standard Linux Shell commands are named with all lowercase characters, so only `abc` would be the standard way to name a program

- Note: Exiting the Linux Shell returns to the QLua app main page
- Run the `exit` command
"""

```
exit
```


AndroidQLua\Console Run a Program

AndroidOS LuaCode UserAction
"""
[Lua console]
- Note: I had problems using the `LoadString` function with the `loadfile` command
- - In the Lua code, replace any references to the `LoadString` function with the `Load` function
- - The `Load` command did not need extra escaping like`\\r` for the parameter, so replace `\\r` with `\r` when using the `Load` command
- Save the result of the loadfile command to create a new function from the file
"""

```
urfile_fn=loadfile('/sdcard/qlua5/ur_file.lua')
```

"""
- Note: This added a row to the _G table
- Note: Just typing a function name or a table name shows the type of data stored in the row
"""

```
_G.urfile
```

"""
- Output is `function: 0x#####`
- Note: any command except _G is an implied name lookup in the _G table
"""

```
urfile
```

"""
- Output is also the same `function: 0x####`
- Note: You can run a function by adding parentheses to the end of the function name
- Running a function can load additional functions into the _G table
"""

```
urfile()
```

"""
- Output is the Lua program output
- Note: Any functions or tables added to the _G table are available
- Note: You can load a Lua function and run it on the same line instead of storing the program in a variable by adding an extra pair of parentheses
"""

```
loadfile('/sdcard/qlua5/ur_file.lua')()
```

"""
- Output is the Lua program output

AndroidQLua\Deploy a Program Module

AndroidOS LuaCode FileSystem
"""
Note: The `share/5.3` directory under the QLua5 folder is where Lua looks to load "program modules" that must be loaded to the _G array as a prerequisites to running the current program

[QLua Editor]
- Note: I had problems using the `LoadString` function with the `require` command
- - In the Lua code, replace any references to the `Load` function with the `LoadString` function
- - The `LoadString` command needs extra escaping like`\\r` for the parameter, so replace `\r` with `\\r` when using the `LoadString` command

- [Bottom bar]
- Click button Save-As (Looks like a page with a Plus in the bottom-right corner) -> Open dialog

- [Save As dialog]
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = `share`
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder `share`
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = `5.3`
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder `5.3`
- [Bottom bar]
- File name = UrFileName.lua
- Click button OK (looks like a checkmark)

[File Manager]
- Note: Your Lua program is stored in folder `/sdcard/qlua/share/5.3`

[Lua console]
- Note: The require command to loads and runs a program module
- - Do not include the path or the `.lua` file extension
"""

```
require 'UrFileName'
```

"""
- Output is the Lua program output

AndroidQLua\Editor Run a Program

AndroidOS LuaCode UserAction
"""
[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icon]
- Click button Open file (looks like a Tabbed folder) -> Opens dialog
- Select file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Note: You can change the source code and save again before each run

- [Bottom bar icons]
- Click button Run (looks like a right-arrow play button) -> Navigates page

- [console window]
- Note: The top line shows the current path and the Linux shell command used to show the editor
- Note: The output of your program is below the first line
- Note: The the last line says "Press enter to exit"

AndroidQLua\MxClasses Design

AndroidOS LuaCode FileSystem AssignVariable
"""
I created some default functions that I need to see the key/value pairs in Lua tables

[def.lua]
- [def_tcompile]
- This creates a 'tcompile' function that concatenates a table's string values then loads the result as a new function
- [def_ti]
- This creates a 'ti' function that adds a new numbered row to a table
- [def_tia]
- This clears out a global table variable and creates a 'tia' function that calls the 'ti' function for that table without having to pass it in as a parameter
- [def_printk]
- This creates a 'printk' function that prints all the keys in a table, sorted alphabetically
- [def_printv]
- This creates a 'printv' function that prints all the values in a table, sorted alphabetically
- [def_tcopy]
- This creates a 'tcopy' function that copies all records from one table into another
- [def_printiv]
- This creates a 'printiv' function that prints all the values in a table, in their original order (good for numeric-keyed tables)
- [def_printkv]
- This creates a 'printkv' function that prints all keys and values in a table, sorted by key alphabetically
- [def_ioexec]
- This creates a 'ioexec' function that runs a shell command and returns a table you can store
    - Example: Prints all the .lua files under a directory
"""

```
local ttbFILE = ioexec('find /sdcard/qlua5 -name "*.lua" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)
```

- [def_printio]
- This creates a 'printio' function that runs printiv on the ioexec table
    - Example: printio('ls /storage')

AndroidQLua\MxClasses LoadFile

AndroidOS LuaCode CodeLibrary FileSystem
```
--[under folder /sdcard/qlua5]
--This file can be run by the QLua command "LoadFile" because it uses the Load function instead of the LoadString function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) load(table.concat(ur_table, "\\r"))() end'}
load(table.concat(def_tcompile, "\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  load(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)

AndroidQLua\MxClasses Require Program Module

AndroidOS LuaCode CodeLibrary
```
--[under folder /sdcard/qlua5]
--Create subdir share/5.3
--Put in a copy of def.lua
--This file can be run by the QLua command "require" because it uses the LoadString function instead of the Load function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) loadstring(table.concat(ur_table, "\\r"))() end'}
loadstring(table.concat(def_tcompile, "\\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  loadstring(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
--[[
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)
--]]

AndroidQLua\Source Code Editor

AndroidOS LuaCode UserAction
"""
[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icons]
- Click button New File (looks like a page with a Plus sign) -> Opens dialog

- [New file dialog]
- Click option Blank file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Enter some text

- [Bottom bar]
- Click button Save (looks like a 3.5" floppy disk)

[SDCard file list]
- Note: The file gets saved in the folder /sdcard/qlua5

AndroidScreenshot

DOC
<<glbl_article_list>>

AndroidScreenshot\Screenshot Easy

AndroidOS Video Extract
"""
[Google Play Store app]
- Install app Screenshot Easy by Ice Cold Apps
- Note: Contains ads

AndroidVNC

DOC
<<glbl_article_list>>

AndroidVNC\RealVNC remote control Windows O/S

AndroidOS Video UserAction WindowsOS
"""
Windows O/S

[https://www.realvnc.com/en/connect/download/viewer/windows/]
- Install app VNC Connect for Windows

[VNC Connect for Windows app]
- Connects to login
- Note: Allows connection by RealVNC's VNC Viewer app on Android O/S

Android O/S

[Google Play Store]
- Install app VNC Viewer by RealVNC Limited

[VNC Viewer app]
- Connects to login
- [Alt tab]
- Use Ctrl-Esc to get to the Windows Start Menu and the Task Bar to change windows

AndroidVNC\Remote Control Android Device

AndroidOS UserAction Video
"""
Install app AnyDesk by AnyDesk Software GmbH
- https://play.google.com/store/apps/details?id=com.anydesk.anydeskandroid&hl=en_US&gl=US

Install on both Android devices
- The other installed devices will show when connected to the same WiFi network
- Automatically figures out how to use the controlling Android device's touch screen

AndroidWebDav

DOC
<<glbl_article_list>>

AndroidWebDav\BestDAV

AndroidOS FileSystem UserAction
"""
Access files on Android device from a networked Windows computer

[Andrdoid OS]
- [Google Play Store]
- Install app WebDAV Server - BestDAV
- - Free or Pro edition

[WebDAV Server]
- [Main page, top bar]
- Note: Folders not listed under the "Folders" button automatically has read-only access via WebDav
- Click button Settings -> nav
- [Settings page]
- Website Home Directory = /storage
- [Main page, bottom bar]
- Click button Start Server
- Note: The server's network URL starts with "http://" and ends with ":8080"
- - Sample = http://192.168.0.15:8080

[Windows computer]
- [browser]
- Address = http://192.168.0.15:8080
- Click link Get the file list -> nav
- Note: The directory shows the "external" SD Card name (if any) and "enc_emulated"
- To see the "internal" /sdcard folder on the android device,
- - Click link "enc_emulated" -> /_dir.cgi?dir=%2Fenc_emulated
- - Edit the address to say /_dir.cgi?dir=%2Femulated/0

- [Windows Explorer]
- Address = \\192.168.0.15@8080\DavWWWRoot
- Note: The directory shows the "external" SD Card name (if any) and "emulated", "enc_emulated", and "self"
- To see the "internal" /sdcard folder on the android device,
- - Click link "emulated" -> http://192.168.0.15:8080/emulated
- - Edit the address to say http://192.168.0.15:8080/emulated/0

btn Delete Cards

$:/positivesigner/base-install
<$button>
<$list filter="[tag[ARTICLE]] [tag[IMG]]"><$action-deletetiddler $tiddler=<<currentTiddler>> /></$list>
Del ARTICLE and IMG cards
</$button>

Card filter

INDEX
\define tag_button(ur_field, ur_tag_name)
<$button>
<$action-setfield $tiddler="$ur_field$" text="$ur_tag_name$"/>
<$action-navigate $to="Tag pairs"/>
<<tag-pill "$ur_tag_name$">>
</$button>
\end

{{ext TW Return}}

<$list variable=on_twcard filter="[<tv-config-toolbar-icons>!match[no]]">
<$button>
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/tag_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/text_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/text_input_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
Clear filters
</$button><br>

Text search: <$edit-text tiddler="$:/state/popup/text_input_e1" field=text default="" placeholder="[Type to search for text 1]" autoHeight=yes tag=input/>
<$edit-text tiddler="$:/state/popup/text_input_e2" field=text default="" placeholder="[Type to search for text 2]" autoHeight=yes tag=input/>
<$button>
<$action-setfield $tiddler="$:/state/popup/text_e1" text={{$:/state/popup/text_input_e1}}/>
<$action-setfield $tiddler="$:/state/popup/text_e2" text={{$:/state/popup/text_input_e2}}/>
Search text
</$button><br>

<$list variable=text_prefix_e1 filter="[[$:/state/popup/text_e1]get[text]else[]]">
<$list variable=text_lowercase_e1 filter="[<text_prefix_e1>lowercase[]]">
<$list variable=text_prefix_e2 filter="[[$:/state/popup/text_e2]get[text]else[]]">
<$list variable=text_lowercase_e2 filter="[<text_prefix_e2>lowercase[]]">
<$list variable=tag_prefix_e1 filter="[[$:/state/popup/tag_e1]get[text]uppercase[]else[]]">
<$list variable=count_any_input filter="[<text_prefix_e1>] [<text_prefix_e2>] [<tag_prefix_e1>] +[each:value[]!match[]count[]]">

<$list variable=tag_list filter="[tags[]each:value[]!prefix[$:]sort[]]">
<$list variable=all_caps_taglist filter="[<tag_list>uppercase[]]">
<$list variable=filter_all_capslist filter="[<tag_list>!match<all_caps_taglist>]">
<$list variable=card_count filter="[tag<tag_list>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>count[]!match[0]]">@@white-space:nowrap;<$macrocall $name=tag_button ur_field="$:/state/popup/tag_e1" ur_tag_name=<<tag_list>> /> ( <<card_count>> )@@
</$list><!--card_count-->
</$list><!--filter_all_capslist-->
</$list><!--all_caps_taglist-->
</$list><!--tag_list
-->

<$list variable=filter_any_input filter="[<count_any_input>!match[0]]">
<$list variable=tag_e1 filter="[search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>tags[]each:value[]!prefix[$:]sort[]]">
<$list variable=all_caps_tage1 filter="[<tag_e1>uppercase[]]">
<$list variable=filter_all_capse1 filter="[<tag_e1>!match<all_caps_tage1>]">
<$list variable=filter_prefix_e1 filter="[<all_caps_tage1>prefix<tag_prefix_e1>]">
<$list variable=card_count filter="[tag<tag_e1>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>count[]]">
<$list variable=filter_card_found filter="[<card_count>!match[0]]">
<$macrocall $name=tag_button ur_field="$:/state/popup/tag_e1" ur_tag_name=<<tag_e1>> />

<$list variable=link_title filter="[tag<tag_e1>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>]">

<<<
<$link to=<<link_title>> /> (<$list variable=disp_tag filter="[<link_title>tags[]sort[]]"> <<disp_tag>> </$list>)

<$list variable=filter_anytext_e1 filter="[<text_prefix_e1>!match[]]">
<$list variable=found_leadingtext_e1 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e1>butlast[]]">

* <$list variable=sample_leadingtext_e1 filter="[<found_leadingtext_e1>split[ ]last[7]join[ ]]">
<$text text=<<sample_leadingtext_e1>> />
''<$text text=<<text_lowercase_e1>> />''
</$list><!--sample_leadingtext_e1-->
<br>
</$list><!--found_leadingtext_e1-->
<$list variable=found_trailingtext_e1 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e1>butfirst[]]">

* <$list variable=sample_trailingtext_e1 filter="[<found_trailingtext_e1>split[ ]first[7]join[ ]]">
''<$text text=<<text_lowercase_e1>> />''
<$text text=<<sample_trailingtext_e1>> />
</$list><!--sample_trailingtext_e1-->
</$list><!--found_trailingtext_e1-->
</$list><!--filter_anytext_e1
-->

<$list variable=filter_anytext_e2 filter="[<text_prefix_e2>!match[]]">
<$list variable=found_leadingtext_e2 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e2>butlast[]]">

* <$list variable=sample_leadingtext_e2 filter="[<found_leadingtext_e2>split[ ]last[7]join[ ]]">
<$text text=<<sample_leadingtext_e2>> />
''<$text text=<<text_lowercase_e2>> />''
</$list><!--sample_leadingtext_e2-->
<br>
</$list><!--found_leadingtext_e2-->
<$list variable=found_trailingtext_e2 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e2>butfirst[]]">

* <$list variable=sample_trailingtext_e2 filter="[<found_trailingtext_e2>split[ ]first[7]join[ ]]">
''<$text text=<<text_lowercase_e2>> />''
<$text text=<<sample_trailingtext_e2>> />
</$list><!--sample_trailingtext_e2-->
</$list><!--found_trailingtext_e2-->
</$list><!--filter_anytext_e2
-->

<<<
</$list><!--link_title-->
</$list><!--filter_card_found-->
</$list><!--card_count-->
</$list><!--filter_prefix_e1-->
</$list><!--filter_all_capse1-->
</$list><!--all_caps_tage1-->
</$list><!--tag_e1-->
</$list><!--filter_any_input-->
</$list><!--count_any_input-->
</$list><!--tag_prefix_e1-->
</$list><!--text_lowercase_e2-->
</$list><!--text_lowercase_e1-->
</$list><!--text_prefix_e2-->
</$list><!--text_prefix_e1-->
</$list><!--on_twcard-->

[[Search All Code |View All Code]]

[[___|Recent Entries]]

ChromeBrowser

DOC
<<glbl_article_list>>

ChromeBrowser\Browse Local Folders

Browser FileSystem Extract
"""
Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome

[Google Chrome app]
- [Windows O/S]
- Navigate to file:///C:/
- [Android O/S]
- Navigate to file:///sdcard/

- [Directory list]
- Select which sub-folder you want to bookmark
- [Navigation bar, Top-right icons]
- Click button Bookmark Page (looks like a star shape) -> Opens dialog
- [Bookmark Added dialog]
- Name = UrShortName
- Click button Done -> Closes dialog
- [Navigation bar]
- Address = UrShortName -> Shows suggestions
- [Suggestion list]
- Select the suggested link -> Navigates page

ChromeBrowser\Command Line Options

Browser AssignVariable CodeLibrary
"""
The command line options are usually two hyphens followed by a keyword

- Note: The incognito option starts the browser with an open Incognito window
"""

```
–incognito
```

"""
- Note: Google Chrome Portable has these parameters automatically included when calling the Chrome.exe program.
"""

```
–user-data-dir="%TEMP%"
–disk-cache-dir="%TEMP%\GoogleChromePortable\Cache"
```

"""
To override the user data and all the cache directories:

- Find the INI file in the PortableApp sub-directory
"""

```
GoogleChromePortable\Other\Source\GoogleChromePortable.ini
```

"""
- Copy it to the program main directory
"""

```
GoogleChromePortable\GoogleChromePortable.ini
```

"""
- [Edit the file]
- CacheInTemp = false
- Save file
- Note: When you restart Google Chrome Portable, cached files will be stored under the program's folder
"""

```
C:\TJBF\zPortableInstalls\Chrome\Data\profile\Default\*Cache\
```

ChromeBrowser\Turn off Chrome spell check highlighting

Browser CodeLibrary Text Formatting
"""
[Google Chrome app]
- [Top-right icons]
- Click the three-dots menu, option Settings -> Navigates page
- [Settings page[
- search for Language -> Filters results
- [Languages section]
- checkbox Spell check = clear -> Chrome will not highlight spelling errors

Code Samples

INDEX
{{ext TW Return}}

<<list-links filter:"[tag[DOC]sort[title]]">>

[[___|Recent Entries]]

css alternating-rows

$:/tags/Stylesheet META
.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}

DivPop btn

$:/tags/ViewToolbar $:/positivesigner/div-pop
<$list variable=cur_card filter="[all[current]]">
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=<<cur_card>>/>
<$action-sendmessage $message="tm-close-tiddler" $param="pop_right"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{DivPop.svg}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text="Popup over Sidebar"/></span>
</$list>
</$button>
</$list>

DivPop glbl

$:/tags/BelowStory $:/positivesigner/div-pop
<$list variable=cur_divpop_card filter="[{$:/state/popup/DivPopTitle}is[tiddler]]">
<div style="
position: fixed;
top: 0px;
right: 0px;
width: 350px;
border: 3px solid;
background: white;
bottom: 0%;
">
<div style="overflow-y: scroll; height: 100%;">
<$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
close
</$button>
&nbsp;&nbsp;&nbsp;<$reveal type="match" state="$:/state/popup/$ur_pk$" text="show"><$button set="$:/state/popup/$ur_pk$" setTo="hide">show</$button>&nbsp;&nbsp;&nbsp;<$link to=<<cur_divpop_card>> ><<cur_divpop_card>>
</$link>
<$list variable=cur_text filter="[<cur_divpop_card>get[text]]">
<$codeblock code=<<cur_text>> /></$list>
</$reveal>
<$reveal type="nomatch" state="$:/state/popup/$ur_pk$" text="show"><$button set="$:/state/popup/$ur_pk$" setTo="show">code</$button>&nbsp;&nbsp;&nbsp;<$link to=<<cur_divpop_card>> ><<cur_divpop_card>>
</$link>
<$tiddler tiddler=<<cur_divpop_card>> >
<$transclude mode="block" />
</$tiddler>
</$reveal>
</div>
</div>
</$list>

DivPop.svg

$:/positivesigner/div-pop
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
   sodipodi:docname="PopupSidebar.svg"
   id="svg52"
   version="1.1"
   height="22pt"
   width="22pt"
   viewBox="0 0 128 128"
   class="tc-image-close-button tc-image-button">
  <metadata
     id="metadata58">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <defs
     id="defs56">
    <inkscape:perspective
       id="perspective60"
       inkscape:persp3d-origin="64 : 36.371105 : 1"
       inkscape:vp_z="128 : 43.054765 : 1"
       inkscape:vp_y="0 : 313.29655 : 0"
       inkscape:vp_x="0 : 43.054765 : 1"
       sodipodi:type="inkscape:persp3d" />
  </defs>
  <sodipodi:namedview
     inkscape:current-layer="svg52"
     inkscape:window-maximized="0"
     inkscape:window-y="27"
     inkscape:window-x="61"
     inkscape:cy="12.415296"
     inkscape:cx="21.019608"
     inkscape:zoom="8"
     showgrid="false"
     id="namedview54"
     inkscape:window-height="480"
     inkscape:window-width="820"
     inkscape:pageshadow="2"
     inkscape:pageopacity="0"
     guidetolerance="10"
     gridtolerance="10"
     objecttolerance="10"
     borderopacity="1"
     bordercolor="#666666"
     pagecolor="#ffffff" />
  <g
     id="g50"
     fill-rule="evenodd" />
  <rect
     y="13.090909"
     x="10.909091"
     height="104.72727"
     width="111.27273"
     id="rect85"
     style="fill:#cccccc;stroke-width:4.36364" />
  <rect
     y="19.636366"
     x="19.09091"
     height="89.454567"
     width="95.454552"
     id="rect92"
     style="fill:#ffffff;stroke-width:4.36364" />
  <rect
     y="58.909092"
     x="50.727272"
     height="10.909091"
     width="42.545452"
     id="rect94"
     style="fill:#cccccc;stroke-width:4.36364" />
  <path
     id="path96"
     d="m 61.090909,34.363636 c 32.181818,24.545458 32.181818,24.545458 32.181818,24.545458 v 0"
     style="fill:#cccccc;stroke:#cccccc;stroke-width:4.36364px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
  <path
     id="path98"
     d="M 64.909091,95.999999 C 93.272727,69.818185 93.272727,69.818185 93.272727,69.818185"
     style="fill:#b3b3b3;stroke:#cccccc;stroke-width:4.36364px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
  <rect
     y="16.90909"
     x="86.727272"
     height="94.909088"
     width="8.181818"
     id="rect100"
     style="fill:#cccccc;stroke-width:4.36364" />
</svg>

Excel VBA

DOC
<<glbl_article_list>>

Excel VBA\Get Worksheet

ExcelCode CodeLibrary FileSystem
```
Dim wksDATA As Worksheet
Set wksDATA = Application.ActiveSheet
wksDATA.Cells(2,2).Value = "Hi"

'Press F5 to run the macro
'Note: Cell B2 says "Hi"

Excel VBA\New Macro

ExcelCode FileSystem AssignVariable
"""
[Microsoft Excel application]
- [Ribbon menus]
- View menu, option Record Macro -> Starts recording
- View menu, option Stop Recording -> Stops recording
- View menu, option Macros -> Opens dialog

[Macro list]
- Click button Edit Macro -> Opens window

[VBA Editor]
- You can change the name of the macro and add commands
- Close the editor

[Microsoft Excel application]
- Save the file as a Macro-Enabled workbook (mwb)

Excel VBA\Power Exponent

ExcelCode Numbers Extract
"""
Make sure you put a space between the power operator (^) and the numbers

- CalcResult = 2^5
- Note: This gives a compilation error on 64-bit Excel

- CalcResult = 2 ^ 5
- Note: CalcResult = 32

ext ALAorg Citations bookmarklet

EXT
http://www.ala.org/tools/article/ala-techsource/%E2%80%9Ccitethis%E2%80%9D-building-javascript-bookmarklet-creates-citations-sharing-web

ext Apple.com Safari Meta tags

EXT
https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html

ext CodeAcademy DocType

EXT
https://discuss.codecademy.com/t/why-we-type-before-doctype-what-is-the-role-of-in-doctype-html/60880/3

ext DeveloperSettings HTM

EXT
VBNet_Project\DeveloperSettings\Developer Settings App.html

ext DeveloperSettings ZIP

EXT
VBNet_Project\DeveloperSettings\DeveloperSettings.zip

ext Empty Wiki Setup

EXT
TW Project\Empty Wiki\Empty Wiki.htm

ext FileFormat.Info UnicodeInput

EXT
https://www.fileformat.info/tool/unicodeinput/index.htm

ext FileFormat.Info UnicodeInput.ZIP

EXT
https://www.fileformat.info/tool/unicodeinput/unicodeinput.zip

ext GitHub LukeHorvat Computed Style to Inline

EXT
https://github.com/lukehorvat/computed-style-to-inline-style

ext GoogleDevelopers FullScreen web app

EXT
https://developers.google.com/web/fundamentals/native-hardware/fullscreen/

ext HTML.com DocType

EXT
https://html.com/tags/doctype/

ext JavaScript Closures

EXT
http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html

ext JavaScript Strict Mode

EXT
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

ext JavaScript This Parameter

EXT
http://blog.niftysnippets.org/2008/03/mythical-methods.html

ext JTFAssociates MOTW

EXT
https://jtfassociates.com/using-the-mark-of-the-web-motw/

ext MathiasBynens Rel Icon

EXT
https://mathiasbynens.be/notes/rel-shortcut-icon

ext MetaTags.org Generator

EXT
https://www.metatags.org/all-meta-tags-overview/meta-name-generator/

ext Microsoft DotNet Char ConvertToUTF32

EXT
https://docs.microsoft.com/en-us/dotnet/api/system.char.converttoutf32?view=net-5.0#System_Char_ConvertToUtf32_System_String_System_Int32_

ext Microsoft RemoteDesktop Enable

EXT
https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-allow-access

ext Mozilla.org META tags

EXT
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name

ext MozillaDeveloper CSS Comment

EXT
https://developer.mozilla.org/en-US/docs/Web/CSS/Comments

ext MozillaDeveloper Strict mode

EXT
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

ext MxBase Classes

EXT
VBNet_Project/MxBase/MxBase%20Classes.html

ext Project Check app

EXT
TW Project\Checkapp\Checkapp.htm

ext PSU.edu LangTag

EXT
https://accessibility.psu.edu/foreignlanguages/langtaghtml/

ext Regexp Filter with brackets

EXT
https://tiddlywiki.narkive.com/T5403O4p/tw5-regexp-for-matching-a-tag-tiddlytweeter#post7

ext Regular Expression Quantifiers

EXT
https://www.rexegg.com/regex-quantifiers.html

ext Roman to Decimal ZIP

EXT
VBNet_Project\Examples\Roman_To_Decimal.zip

ext Shuffle List Entries

EXT
TiddlyWiki_Code\Snapshot\mklauber TWPlugin Shuffle.txt.html

ext SitePoint Exports Node.JS

EXT
https://www.sitepoint.com/understanding-module-exports-exports-node-js/

ext SO.com RunTime Net 4.5

EXT
https://stackoverflow.com/questions/8517159/how-do-i-detect-at-runtime-that-net-version-4-5-is-currently-running-your-code

ext SQLite Blob text

EXT
https://stackoverflow.com/questions/15366594/convert-hex-to-text-using-sqlite

ext SQLite DB Browser

EXT
https://sqlitebrowser.org/dl/

ext SQLite Language functions

EXT
https://sqlite.org/lang_corefunc.html

ext SQLite schema information

EXT
https://stackoverflow.com/questions/6460671/sqlite-schema-information-metadata

ext SQLite Top 5 Records

EXT
https://stackoverflow.com/questions/2728999/how-to-get-top-5-records-in-sqlite

ext StackOverflow CSS location

EXT
https://stackoverflow.com/questions/1642212/whats-the-difference-if-i-put-css-file-inside-head-or-body

ext StackOverflow Hide Parent Show Child tag

EXT
https://stackoverflow.com/questions/12956937/display-html-child-element-when-parent-element-is-displaynone

ext StackOverflow Meta UA-Compatible

EXT
https://stackoverflow.com/questions/6771258/what-does-meta-http-equiv-x-ua-compatible-content-ie-edge-do#:~:text=The%20X%2DUA%2DCompatible%20meta%20tag%20allows%20web%20authors%20to,meta%20tag%20in%20certain%20circumstances.

ext Tiddly Wiki Home Button source code

EXT
https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/PageControls/home.tid

ext TiddlyWiki Save Button source code

EXT
https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/PageControls/savewiki.tid

ext TiddlyWiki TopBar Menu

EXT
https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/TopRightBar/menu.tid

ext TW Addon Text Replace

EXT
TiddlyWiki_Code\AddOns\Text Replace Bar.htm

ext TW Create Javascript Plugin

EXT
https://sudonull.com/post/97468-How-to-write-a-plugin-for-TiddlyWiki

ext TW Features

EXT
TiddlyWiki_Code\Features\TW Features.htm

ext TW JS Pretty

EXT
TW Project\JS_Pretty\TW JS Pretty.htm

ext TW Manual

EXT
TiddlyWiki_Code\Snapshot\TheBook - The TiddlyWiki Manual.txt.html

ext TW Return

$:/positivesigner/text-ref
\define TW_Return(ur_url, ur_link_title)
<div style="float:right"><a href="$ur_url$"> ($ur_link_title$)</a></div>
\end
<$list variable=found_index filter="[{$:/info/url/full}split[/]count[]subtract[1]]">
<$list variable=skip_html filter="[<tv-config-toolbar-icons>match[no]]">
<$list variable=return_url filter="[{$:/info/url/full}split[/]butfirst<found_index>first[]split[.html]join[.htm]addprefix[src/]]">
<$macrocall $name=TW_Return ur_url=<<return_url>> ur_link_title="TiddlyWiki view of website" />
</$list><!--found_html-->
</$list><!--skip_html-->
<$list variable=found_html filter="[<tv-config-toolbar-icons>!match[no]]">
<$list variable=return_url filter="[{$:/info/url/full}split[/]butfirst<found_index>first[]split[.html]join[.htm]split[.htm]join[.html]addprefix[../]]">
<$macrocall $name=TW_Return ur_url=<<return_url>> ur_link_title="Static HTML view of website" />
</$list>
</$list><!--found_html-->
</$list><!--found_index-->

ext TW Snapshot Review

EXT
TiddlyWiki_Code\Snapshot\Browse Code tiddlywiki_v5d01d23pre-release.htm

ext TW Snapshot v5d01d23 empty

EXT
TW Project\Snapshot\tw_empty_v5d01d23.html

ext TW Snapshot v5d01d23 main-site

EXT
TW Project\Snapshot\tiddlywiki_v5d01d23_main-site.html

ext TW Snapshot v5d01d23 pre-release

EXT
TW Project\Snapshot\tiddlywiki_v5d01d23_pre-release.html

ext TW Snapshot v5d01d23 update

EXT
TW Project\Snapshot\tiddlywiki_v5d01d23_update.html

ext Unicode Block 00-Basic Latin

EXT
https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)

ext Unicode Block 01-Latin Supplement

EXT
https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)

ext Unicode Block Planes

EXT
https://en.wikipedia.org/wiki/Plane_(Unicode)

ext Unicode Character Database

EXT
http://www.unicode.org/Public/UCD/latest/

ext Unicode Code Block List

EXT
https://en.wikipedia.org/wiki/Unicode_block

ext VBNetScript.EXE

EXT
VBNet_Project\VBNetscript\VBNetScript_EXE.zip

ext VBNetScript.SLN

EXT
VBNet_Project\VBNetscript\VBNetScript_Project.zip

ext W3.org HTML401 Meta

EXT
https://www.w3.org/TR/html401/struct/global.html#h-7.4.4

ext W3.org HTML401 Profiles

EXT
https://www.w3.org/TR/html401/struct/global.html#profiles

ext W3Schools DocType

EXT
https://www.w3schools.com/tags/tag_doctype.asp

ext W3Schools Head tag

EXT
https://www.w3schools.com/tags/tag_head.asp

ext W3Schools Meta HTTP-EQUIV

EXT
https://www.w3schools.com/tags/att_meta_http_equiv.asp

ext W3Schools NoScript tag

EXT
https://www.w3schools.com/tags/tag_noscript.asp

ext WestWindCom Net Core Runtime

EXT
https://weblog.west-wind.com/posts/2018/Apr/12/Getting-the-NET-Core-Runtime-Version-in-a-Running-Application

ext WHATWg.org Link Icon

EXT
https://html.spec.whatwg.org/multipage/links.html#rel-icon

ext Wiki Move HTM

EXT
VBNS_Project\Wiki_Move\Wiki Move HTM.htm

ext Windows Alt-Numpad Unicode

EXT
https://conemu.github.io/en/AltNumpad.html

ext Windows Environment Variable List

EXT
https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables#bkmk-1

ext Windows Terminal Unicode Support

EXT
https://devblogs.microsoft.com/commandline/introducing-windows-terminal/

ext WindowsCLI Unicode Support

EXT
https://www.generacodice.com/en/articolo/203149/How-to-use-unicode-characters-in-Windows-command-line

FFMPeg

DOC
<<glbl_article_list>>

FFMPeg\Extract Captions file

WindowsOS Text Extract
```
chcp 65001
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" "C:\UrPath\UrFile.srt"
pause

FFMPeg\Extract JPG files

Video Extract WindowsOS
"""
[ffmpeg.exe command-line options]
- `-ss 05:00 -t 10:00` means start at 5min and end 10min later at 15min
- `-r 1` means 1 frame per second
- `-r 0.25` means 1 frame every 4 seconds
- `-r 0.083` means 1 frame every 12 seconds, or 5 frames per minute, 50 frames out of every ten minutes, or 300 frames every hour

- IrfanView can create a portrait contact sheet with 5 columns, representing one min of video per row, 10 rows per page showing 10 minutes of video
- IrfanView can create a landscape contact sheet with 7 columns is one 3 min per 2 rows, 7 rows per page showing 10.5 minutes of video, two pages showing 21 minutes

- Open on thumbnail image with IrfanView, select File menu Thumbnails option
- Select all files in the folder, select File menu Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

"""

```
chcp 65001
rem -ss 05:00 -t 10:00 means start at 5min and end 10min later at 15min
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" -r 0.083 -s 320x180 "UrPath\UrSubdir\output_%%04d.jpg"


Font Size

$:/positivesigner/text-ref
<$list variable=cur_entry filter="[all[tiddlers]!suffix[.js]!suffix[.css]!match[$:/core]!prefix[$:/config/]!prefix[$:/DefaultTiddlers]!prefix[$:/Import]!match[$:/isEncrypted]!prefix[$:/language/]!prefix[$:/theme]!prefix[$:/temp/]!prefix[$:/status/]!match[$:/StoryList]!match[$:/HistoryList]!match[$:/SiteTitle]!match[$:/SiteSubtitle]!prefix[$:/state/]count[]]">
Specific prefix filter: <<cur_entry>> cards
</$list>

<$list variable=cur_entry filter="[all[tiddlers]!is[system]] [prefix[$:/positivesigner]] +[count[]]">

Non-system plus system PositiveSigner filter: <<cur_entry>> cards
</$list>


<$button>
<$list variable=cur_card filter="[!is[system]!prefix[Draft of]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[append[COPY]]"/>
</$list>
Append COPY tag to all non-system cards
</$button><br>

<$button>
<$list variable=cur_card filter="[tag[COPY]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[remove[COPY]]"/>
</$list>
Remove COPY tag from all cards
</$button><br>


<$button>
{{keyboard action FontLarge}}
Big Font
</$button>

<$button>
{{keyboard action FontNormal}}
Normal Font
</$button>

[[Panel]]

!!Cards where has[tags] does not work

<$list variable=cur_card filter="[is[tiddler]]">
<$list variable=has_tags_test filter="[<cur_card>!has[tags]count[]] [<cur_card>has[tags]count[]] +[sum[]match[0]]">

<$link to=<<cur_card>> />
</$list><!--has_tags_test-->
</$list><!--cur_card-->

!!Cards with no tags

<$list variable=cur_card filter="[!is[system]is[tiddler]!has[tags]!prefix[Draft of]!prefix[$:/state/]!prefix[$:/library/]!prefix[$:/boot/]!prefix[$:/temp/]!match[$:/core]!match[$:/Import]!match[$:/isEncrypted]!match[$:/SiteSubtitle]!match[$:/SiteTitle]!prefix[$:/status/]!match[$:/StoryList]!match[$:/HistoryList]!match[$:/theme]!match[$:/themes/tiddlywiki/snowwhite]!match[$:/themes/tiddlywiki/vanilla]]">
<$list variable=has_parent_card filter="[<cur_card>split[\]count[]match[1]]">

<$link to=<<cur_card>> />
</$list><!--has_parent_card-->

<$list variable=has_parent_card filter="[<cur_card>split[\]count[]!match[1]]">
<$list variable=parent_card_exists filter="[<cur_card>split[\]first[]!is[tiddler]]">

<$link to=<<cur_card>> />
</$list><!--parent_card_exists-->
</$list><!--has_parent_card-->
</$list><!--cur_card-->


[[parm SkipSaveExportHTML]]

[[btn Delete Cards]]

GitCLI

DOC
<<glbl_article_list>>

GitCLI\Checkout hash

FileSystem GitCode Extract
```
@echo off
SET ur_repo=
SET ur_branch=
"C:\UrPath\git.exe" -C %ur_repo% checkout -b test-branch %ur_branch%

rem Use GitHub Desktop to delete the branch

GitHubDesktop

DOC
<<glbl_article_list>>

GitHubDesktop\Git executable

WindowsOS FileSystem GitCode
"""
When GitHub Desktop is installed, the Git.exe program is placed in the %APPDATA% folder. There is one sub-directory for each version of Git that has been downloaded. Look for the latest version-numbered folder.
"""

```
C:\Users\UrUser\AppData\Local\GitHubDesktop\app-UrVersion
```

"""
Under the app-UrVersion folder, find the Git.exe program
"""

```
app-UrVersion\resources\app\git\cmd\git.exe

GoogleContacts

DOC
<<glbl_article_list>>

GoogleContacts\Export as CSV

Service FileSystem Extract
"""
[https://contacts.google.com/]
- [Left-side menu]
- Click button Export -> Opens dialog
- Export contacts = Contacts (total count)
- Export as = Google CSV
- Click button Export -> Downloads file, Closes dialog

[CSV file]
- Header fields =
"""

```
Name
Given Name
Additional Name
Family Name
Yomi Name
Given Name Yomi
Additional Name Yomi
Family Name Yomi
Name Prefix
Name Suffix
Initials
Nickname
Short Name
Maiden Name
Birthday
Gender
Location
Billing Information
Directory Server
Mileage
Occupation
Hobby
Sensitivity
Priority
Subject
Notes
Language
Photo
Group Membership
E-mail 1 - Type
E-mail 1 - Value
E-mail 2 - Type
E-mail 2 - Value
Phone 1 - Type
Phone 1 - Value
Phone 2 - Type
Phone 2 - Value
Address 1 - Type
Address 1 - Formatted
Address 1 - Street
Address 1 - City
Address 1 - PO Box
Address 1 - Region
Address 1 - Postal Code
Address 1 - Country
Address 1 - Extended Address
Organization 1 - Type
Organization 1 - Name
Organization 1 - Yomi Name
Organization 1 - Title
Organization 1 - Department
Organization 1 - Symbol
Organization 1 - Location
Organization 1 - Job Description
Relation 1 - Type
Relation 1 - Value
Website 1 - Type
Website 1 - Value
```

- Header line =

```
Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initials,Nickname,Short Name,Maiden Name,Birthday,Gender,Location,Billing Information,Directory Server,Mileage,Occupation,Hobby,Sensitivity,Priority,Subject,Notes,Language,Photo,Group Membership,E-mail 1 - Type,E-mail 1 - Value,E-mail 2 - Type,E-mail 2 - Value,Phone 1 - Type,Phone 1 - Value,Phone 2 - Type,Phone 2 - Value,Address 1 - Type,Address 1 - Formatted,Address 1 - Street,Address 1 - City,Address 1 - PO Box,Address 1 - Region,Address 1 - Postal Code,Address 1 - Country,Address 1 - Extended Address,Organization 1 - Type,Organization 1 - Name,Organization 1 - Yomi Name,Organization 1 - Title,Organization 1 - Department,Organization 1 - Symbol,Organization 1 - Location,Organization 1 - Job Description,Relation 1 - Type,Relation 1 - Value,Website 1 - Type,Website 1 - Value
```

- Sample data 1

```
.me,.me,,,,,,,,,,,,,,,,,,,,,,,,,,,Imported 8/5/16 ::: * myContacts,,,,,Mobile,5554443333 ::: 16665554444,,,,,,,,,,,,,,,,,,,,,,,
```

- Sample data 2

```
UrContactName,UrContactFirstName,,UrContactLastName,,,,,,,,,,,,,,,,,,,,,,,,,* myContacts,,,,,Mobile,(444) 333-2222,,,,,,,,,,,,,,,,,,,,,,,
```

GoogleGmail

DOC
<<glbl_article_list>>

GoogleGmail\Export as MBOX

Service Extract FileSystem
"""
[https://takeout.google.com/]
- [Products section]
- Click link Deselect All
- [Mail section]
- checkbox = set
- [End of Page section]
- Click button Next Step -> Navigates section
- [Choose file type, frequency & destination]
- Frequency = Export once
- File type = .zip
- File size = 2 GB
- Click button Create Export -> Navigates section
- [Export Progress]
- Note: Google is creating a copy of files from Mail. This process can take a long time (possibly hours or days) to complete. You'll receive an email when your export is done.

[https://mail.google.com/]
- [Message with title "Archive of Google data requested"]
- Note: You can ignore the message or click the link to verify it was you
- [Message with title "Your Google data is ready to download"]
- Click button Download Your Files -> Opens tab

[Google Takeout form]
- Re-enter your password
- [Record where Export = Mail]
- Note: The size of the export file is also in the Export column
- Click button Download -> Downloads file
- Note: The file may take a long time to download depending on your internet connection and the size of the file

[ZIP file]
- Extract the ZIP file to a folder

[Takeout folder]
- Open the archive_browser.html -> Opens browser

[Archive Browser page]
- [File Formats tab]
- Note: An mbox is a way of storing mail messages and is supported by common mail clients like Microsoft Outlook, Mozilla Thunderbird, and Apple's Mail program. These files are most easily opened by a dedicated mail client like those listed above

[Takeout\Mail folder]
- [All mail Including Spam and Trash.mbox]
- Use Mozilla Thunderbird to read the MBOX file
- OR Split this file into smaller text files... [[somehow |VBNetCode\Copy File Lines]]
- Format:

Record Start = Leading "From " <- Including the space
Tags = "WordsWithoutSpaces:" <- no spaces in tag name
Tag continuation values = " Every Line With Leading Space Or Tab After Tag Name"
Email Content = "First line that is not a tag or tag continuation -> through last line before next leading " "From "

GoogleGmail\MBOX file parsing test

Service Extract Text
```
start "" "%~dp0\MxClasses\VBNetScript.exe" /path=%0 & exit
MxClasses\MxBaseEc12.vb
RetVal = Mx.Want.TextFile_Split_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.TextFile_Split_errhnd
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub TextFile_Split(ret_message As Strap)
			Dim tabchr = CHR(9)
			Dim flnDATA = FileNamed().d("C:\Users\Dad\Downloads\Takeout\Mail\All mail Including Spam and Trash.mbox")
			Dim intLINE_COUNT = 0
			Dim sdaPREFIX_SKIPPED = New Sdata
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), False, gUTF8_FileEncoding)
				Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
				    Dim bolINCLUDE_INDENTED_LINES = False
					Dim bolHTML_TEXT = False
					Dim bolPLAIN_TEXT = False
					Dim bolSKIP_TEXT = False
					While stmDATA.EndOfStream = False
						Dim strLINE = stmDATA.ReadLine()
						If strLINE.Length = 0 Then
						
						ElseIf Left(strLINE, 5) = "From " AndAlso
						  Len(strLINE) = 59 Then
						    bolINCLUDE_INDENTED_LINES = False
							bolHTML_TEXT = False
							bolPLAIN_TEXT = False
							bolSKIP_TEXT = False
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine(strLINE)
							intLINE_COUNT += 1
						
						ElseIf bolSKIP_TEXT Then
						
						ElseIf bolPLAIN_TEXT Then
							If strLINE.Trim.Length > 0 Then
								Dim bolCUR_HTML = False
								Dim intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									bolCUR_HTML = True
									
									End If
								
								If Left(strLINE, 16) = "X-Attachment-Id:" OrElse
								  Left(strLINE, 32) = "Content-Transfer-Encoding:base64" Then
									bolSKIP_TEXT = True
									
									End If 'strLINE
								
								If bolHTML_TEXT = False Then
									stmOUT_FILE.WriteLine(strLINE)
									intLINE_COUNT += 1
								
								ElseIf bolCUR_HTML Then
									Dim strTEXT = strLINE
									While intFOUND_SPRTR > 0
										Dim strPREFIX = Mid(strTEXT, 1, intFOUND_SPRTR - 1)
										Dim strTAG = Mid(strTEXT, intFOUND_SPRTR)
										intFOUND_SPRTR = InStr(strTAG, ">")
										If intFOUND_SPRTR = 0 Then
											strTEXT = strPREFIX
										
										Else
											strTEXT = strPREFIX & Mid(strTAG, intFOUND_SPRTR + 1)
											intFOUND_SPRTR = InStr(strTEXT, "<")
											
											End If 'intFOUND_SPRTR
										
										End While 'intFOUND_SPRTR
									
									If strTEXT.Trim.Length > 0 Then
										stmOUT_FILE.WriteLine(strTEXT)
										intLINE_COUNT += 1
										
										End If
									
									End If 'intFOUND_SPRTR
									
								End If 'strLINE
							
						ElseIf (Left(strLINE, 1) = s OrElse Left(strLINE, 1) = tabchr) AndAlso
						  bolINCLUDE_INDENTED_LINES Then
							'stmOUT_FILE.WriteLine(strLINE)
							'intLINE_COUNT += 1
						    
						Else 'strLINE
						    bolINCLUDE_INDENTED_LINES = False
							Dim strPREFIX = mt
						    Dim intFOUND_SPRTR = InStr(strLINE, ":")
							If intFOUND_SPRTR > 0 Then
							    strPREFIX = Mid(strLINE, 1, intFOUND_SPRTR)
								If InStr(strPREFIX, tabchr) > 0 OrElse
								  InStr(strPREFIX, s) > 0 Then
									strPREFIX = mt
									
									End If
								
								End If
							
							If strPREFIX = "Content-Type:" OrElse
							  strPREFIX = "Subject:" OrElse
							  strPREFIX = "To:" OrElse
							  strPREFIX = "Date:" OrElse
							  strPREFIX = "From:" Then
								bolINCLUDE_INDENTED_LINES = True
								stmOUT_FILE.WriteLine(strLINE)
								intLINE_COUNT += 1
							
							ElseIf Right(strPREFIX, 1) = ":" Then
								bolINCLUDE_INDENTED_LINES = True
								If sdaPREFIX_SKIPPED.Contains(strPREFIX) = False Then
									sdaPREFIX_SKIPPED.d(strPREFIX)
									
								    End If
							
							ElseIf strPREFIX = "" Then
							    bolPLAIN_TEXT = True
								intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									
									End If
								
								End If 'strPREFIX
							
							End If 'strLINE
						
						If intLINE_COUNT >= 100000 Then
							Exit While
							
							End If
						
						End While 'stmDATA
					
					End Using 'stmDATA
				
				End Using 'stmOUT_FILE
			
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("PREFIX_SKIPPED.TXT"), False, gUTF8_FileEncoding)
				Call sdaPREFIX_SKIPPED.Sort()
				For Each strENTRY In sdaPREFIX_SKIPPED
					stmOUT_FILE.WriteLine(strENTRY)
					
					Next strENTRY
				
				End Using 'stmOUT_FILE

			ret_message.Clear.d(intLINE_COUNT.ToString)
			
			End Sub 'TextFile_Split

        Public Shared Function TextFile_Split_errhnd() As Strap
            Dim stpRET = Strapd()
            TextFile_Split_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call TextFile_Split(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'TextFile_Split_errhnd
    End Class 'Want
End Namespace 'Mx

GooglePlay

DOC
<<glbl_article_list>>

GooglePlay\Share purchased apps with another account

Service FileSystem UserAction
"""
[Play Store app]
- [Top-left icon]
- Click the three-lines menu, option `Family Library` -> Navigates page
- Note: There are two Sections
- - `Added by [Other]`
- - `Added by you`

If the purchased app you want to share is not shown under the `Added by You` section, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option `My apps & games` -> Navigates page
- [Installed tab, or Library tab]
- Choose an app you purchased -> Navigates page
- [App page]
- Note: The checkbox Family Library is a toggle switch
- checkbox Family Library = set -> The app is available to all `Family` logins

If the 'Family' logins does not contain the account you want to access your shared app, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option `Account` -> Navigates page
- [Family tab]
- Click button Manage family members -> Opens dialog
- [Family dialog]
- Click button Invite family members -> Opens dialog
- [Verify CVC dialog]
- Enter your credit card number's CVC number
- Click button Verify -> Closes dialog, Opens dialog
- [Send Invitations dialog]
- Select a contact
- Click button Send

[Added Account email]
- Click the invitation link -> Navigates page
- Note: The Added Account can now use the Play Store app to install the Family Library shared app

GooglePlusCodes

DOC
<<glbl_article_list>>

GooglePlusCodes\Find a Plus Code

Service FileSystem Extract Numbers
"""
[https://plus.codes/map/]
- [Search box, Left-side icon]
- Click the three-lines menu, option Satellite -> Refreshes window
- Click the three-lines menu, option Grid -> Refreshes window
- [Navigate to location]
- When the mouse icon is a hand, double-click to Zoom in
- Each time you click, the location will show as 8 characters, a plus sign, and two suffix characters
- - Example: 73F6C9JH+HR
- The last two Zoom levels allow you to select a single Plus Code rectangle, which has three suffix characters after the plus sign
- - Example: 73F6C9JH+HR7
- Copy the browser address bar
- - Example: https://plus.codes/73F6C9JH+HR7

- Note: You can email the page link to someone
- - They will have to turn on the satellite and / or grid options again

- Note: You can use the browser to bookmark the current page
- - Android O/S Chrome can create a desktop shortcut to the current website page (when not in Incognito mode)

- Note: The plus codes are 8 characters, a plus, and two or three suffix characters
- - The bottom of the Plus.Codes website's map only temporarily shows the three suffix characters after you click, quickly reverting to show only two suffix characters
- - You can still see all three suffix characters in the address bar

- [Bottom location code bar, Right-side icon]
- Click button Navigate (looks like a Right-Turn Only road sign) -> Navigates to Google Maps website
- Note: Android O/S Chrome app will ask to Stay On Web or Use The App
- - Click button Use The App to open the Google Maps app

HTML CSS

DOC
<<glbl_article_list>>

HTML CSS\Comment Declaration

HTMLCode Text
!! HTML 5 document

* Declaration Name = `--`
* Content = unprocessed text, except for the character sequence double-hyphen close-tag ( `-->` )
* Note: HTML declarations are not tags, because the have an exclamation mark ( `!` ) before the declaration name / code
* Note: XML documents have a requirement that a double-hyphen ( `--` ) must itself be doubled ( `----` ) when used in a comment declaration, but HTML 5 has no such requirement


!! Sample code for HTML 5 Comment

```
<!-- a text editor can see the comment text -->
```


HTML CSS\Comment MOTW Declaration

HTMLCode Text Browser
!! HTML document viewed in Internet Explorer

* Comment text sequence:

<<<
* `<!--` and optional whitespace
* `saved from url=(`
* the number of characters in the URL string (including the trailing backslash)
* `)`
* the URL string
* optional whitespace and `-->`
<<<

* HTML documents viewed in Internet Explorer show a warning message due to active content, or has a specifically crafted HTML Comment Declaration that names the root URL of the website it is being hosted on
* Note: If this is for a new site, or if the domain is not known, you can use `about:internet` as a valid URL

<<ext "JTFAssociates MOTW">>

!!Sample code

```
<!-- saved from url=(0014)about:internet -->
```

HTML CSS\Compatibility Meta tags

HTMLCode Browser Formatting
!! Declare compatibility version of Microsoft Internet Explorer web browser

* tag name = `meta`
* `http-equiv` attr = `X-UA-Compatible`
* `content` attr = `IE=Edge` or (`IE=11`, `IE=EmulateIE11`, and similar version number pairs)
* Note: Use this tag if you need features specific to an older version of IE like IE9 or IE8
* Note: If you only support the latest browsers (IE11 and/or Edge) then this tag will not affect the web page's behavior until another version is created

<<<
Internet Explorer begins interpreting markup using the latest version. When Internet Explorer encounters the X-UA-Compatible META tag it starts over using the designated version's engine. This is a performance hit because the browser must stop and restart analyzing the content.
<<<

<<ext "StackOverflow Meta UA-Compatible">>

!! Sample code

```
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
```

<<<
`content="IE=Edge" ` mode tells Internet Explorer to display content in the highest mode available. With Internet Explorer 9, this is equivalent to IE9 mode. If a future release of Internet Explorer supported a higher compatibility mode, pages set to edge mode would appear in the highest mode supported by that version. Those same pages would still appear in IE9 mode when viewed with Internet Explorer 9.
<<<

!! Specify web application runs in full-screen mode on Apple devices

* tag name = `meta`
* `name` attr = `apple-mobile-web-app-capable`
* `content` attr = `yes`
* Note: The default behavior is to use Safari to display web content
* Note: You can determine whether a webpage is displayed in full-screen mode using the window.navigator.standalone Boolean JavaScript property

<<ext "Apple.com Safari Meta tags">>

!! Sample code

<<<
<meta name="apple-mobile-web-app-capable" content="yes" />
<<<

!! Specify the Full Screen's status bar style on Apple devices

* tag name = `meta`
* `name` attr = `apple-mobile-web-app-status-bar-style`
* `content` attr = `default`, `black`, `black-translucent`
* Note: If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar
* Note: This meta tag has no effect unless you first specify full-screen mode as described in apple-apple-mobile-web-app-capable

<<ext "Apple.com Safari Meta tags">>

!! Sample code

```
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
```

!! Leave original formatting of telephone-number formatted strings 

* tag name = `meta`
* `name` attr = `format-detection`
* `content` attr = `telephone=no`
* Note: By default, Safari on iOS detects any string formatted like a phone number and makes it a link that calls the number

<<ext "Apple.com Safari Meta tags">>

!! Sample code

```
<meta name="format-detection" content="telephone=no" />
```

!! Specify web application runs in full-screen mode on Apple devices

* tag name = `meta`
* `name` attr = `mobile-web-app-capable`
* content = `yes`
* Note: This tells the browser to launch the page fullscreen when the user has added it to the home screen
* Note: A better option is to use the Web App Manifest for Chrome, Opera, Firefox, and Samsung browsers

<<ext "GoogleDevelopers FullScreen web app">>

!! Sample code

```
<meta name="mobile-web-app-capable" content="yes"/>
```

HTML CSS\CSS Style definitions

CSSCode Browser FileSystem
!! Place a CSS style-sheet in the HTML document

* tag name = `style`
* `type` attr = `text/css`
* Note: The most recent versions of the HTML spec now permits the &lt;style> tag within body elements
* Note: Putting CSS in body means it is loaded later and the browser starts drawing the interface faster
* Note: Putting CSS in body can decrease page performance due to possible reflows/repaints once the browser hits styles further down in the page tree

<<ext "StackOverflow CSS location">>

!! Sample code

```
<style type="text/css">
```

!! Place a comment inside of a CSS style-sheet

* Start CSS comment text with forward-slash asterisk ( `/*` )
* End CSS comment text with asterisk forward-slash ( `*/` )

<<ext "MozillaDeveloper CSS Comment">>

!! Sample code

```
<style type="text/css">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>
```

HTML CSS\Declare document Content type

HTMLCode Browser Text

HTML CSS\DocType Declaration

EXT
!! HTML 5 document

* Declaration Name = `DOCTYPE`
* Content = `html`
* Note: HTML declarations are not tags, because the have an exclamation mark ( `!` ) before the declaration name / code
* Note: This should be the first non-whitespace characters in the document to be compliant with HTML standards
* Note: HTML5 documents don't really need a DOCTYPE as there is no HTML5 DTD for browsers to refer to, but it is used in HTML5 to make sure the browser doesn’t switch into “quirks” mode and remains in full standards mode

<<ext "W3Schools DocType">>

<<ext "HTML.com DocType">>

<<ext "CodeAcademy DocType">>

!! Sample code for HTML 5 declaration

```
<!DOCTYPE html>
```


HTML CSS\Head section

HTMLCode Browser Formatting
!! Set metadata values for interpreting document contents
* The &lt;head> element is a container for metadata (data about data) and is placed between the &lt;html> tag and the &lt;body> tag
* Metadata describes how to interpret and format the HTML document stored within the &lt;body> tag

<<ext "W3Schools Head tag">>

!! Sample code

```
<head>
  <title>UrTitle</title>
</head>
```

HTML CSS\Hide content

HTMLCode Browser Formatting
!! Hide content until user action

* CSS style name = `display`
* value = `none`
* Note: The entire tag and sub-tag structure is hidden
* Note: To hide the root tag and show a child tag, use CSS styles `visibility: hidden` and `visibility: visible`, though the parent markup will still take up screen real estate

<<ext "StackOverflow Hide Parent Show Child tag">>

HTML CSS\HTTP-EQUIV Document Type

HTMLCode Browser FileSystem
!! Simulate an HTTP Respsonse header

* The http-equiv attribute value `content-type` provides an HTTP header specifying that the character encoding for the document is in the content attribute

<<ext "W3Schools Meta HTTP-EQUIV">>

!! Sample code

```
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
```

HTML CSS\iFrame to Local HTML file

HTMLCode FileSystem Extract
```
<iframe src="UrPath\UrFile.html" scrolling=yes style="border-style:none;height:75%;width:100%" ></iframe>

HTML CSS\Language attribute on tags

HTMLCode Browser Formatting
!! Allow screen-reader to identify the page's default language and / or accent

* tag name = any
* `lang` attr = an ISO-639 Language code
* The official W3C recommendation is to declare the primary language for each Web page with a &lt;...lang => attribute in the &lt;html> tag
* Note: The LANG tag (i.e. the lang="" attribute) is designed to signal screen readers pronunciation engines to switch to another language or accent

<<ext "PSU.edu LangTag">>

!! Sample code

```
<html lang="en-GB">
```

HTML CSS\META Tag names

Browser HTMLCode AssignVariable
!! Identify tool or program used to create the website

* tag name = `META`
* `name` attr = `generator`
* `content` attr = The name of the program you used to create your website
* Note: This tag is automatically inserted by website-generating applications
* Note :People who don’t want to advertise which tool or program they used to create the website can remove this tag from the generated pages

<<ext "MetaTags.org Generator">>

!! Sample code

```
<meta name="generator" content="UrProgramTitle" />
```

!! Identifies the name of the application running in the web page

* tag name = `META`
* name attr = `application-name`
* `content` attr = The application that is dynamically supplying content for the current web page
* Note: isolated web pages shouldn't define an application-name

<<ext "Mozilla.org META tags">>

```
<meta name="application-name" content="UrApplicationTitle" />
```

!! Supply hints about the size of the initial size of the viewport

* tag name = `META`
* `name` attr = viewport'
* `content` attr = comma-separated list of equates
* Note: This is used by mobile devices only
* Note: The default values may vary between devices and browsers
* Note: Disabling zooming capabilities by setting user-scalable to a value of no prevents people experiencing low vision conditions from being able to read and understand page content

<<<
* width = ( A positive integer number ) or ( the text `device-width` )
* height = ( A positive integer) or ( the text `device-height` )
* initial-scale = A positive number between 0.0 and 10.0
* maximum-scale = A positive number between 0.0 and 10.0
* minimum-scale = A positive number between 0.0 and 10.0
* user-scalable = `yes`, `no`
* viewport-fit = `auto', 'contain`, `cover`
<<<

<<ext "Mozilla.org META tags">>

!! Sample code

```
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
```

!! Include developer or company information in document

* tag name = `meta`
* `name` attr = `copyright`, `ur_app_name-version`
* `content` attr = Any text data
* Note: This information is not used by the browser

HTML CSS\Meta Tag Schema

HTMLCode AssignVariable Browser
<<ext "W3.org HTML401 Meta">>

This specification does not define a set of legal meta data properties.
The meaning of a property and the set of legal values for that property should be defined in a reference lexicon called a profile.

<<ext "W3.org HTML401 Profiles">>

The profile attribute of the HEAD specifies the location of a meta data profile.
The value of the profile attribute is a URI.
User agents may use this URI in two ways:

* As a globally unique name.

<<<
User agents may be able to recognize the name (without actually retrieving the profile) and perform some activity based on known conventions for that profile.
For instance, search engines could provide an interface for searching through catalogs of HTML documents, where these documents all use the same profile for representing catalog entries.
<<<

* As a link.

<<<
User agents may dereference the URI and perform some activity based on the actual definitions within the profile (e.g., authorize the usage of the profile within the current HTML document).
This specification does not define formats for profiles.
<<<


HTML CSS\Noscript alternate content

EXT
!! Add content when viewed with JavaScript-disabled browsers

* tag name = `noscript`
* Note: The tag contents are displayed to users that have disabled scripts in their browser or have a browser that doesn't support user action event scripting

<<ext "W3Schools NoScript tag">>

!! Sample code

```
</noscript>
<!--Javascript-disabled browser additional content-->
</noscript>
<!--Ordinary content-->
```

HTML CSS\Padding and Margin

HTMLCode CSSCode Formatting
```
style="margin-left:30px"

style="padding-left:10px"

HTML CSS\Table Rows Alternate

HTMLCode Formatting CSSCode
Stylesheet classes:

```
.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}
```

HTML using class

```
<table class="alternating-rows">
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

HTML CSS\Website icon

HTMLCode Browser Formatting FileSystem
!! Show an icon next to the Website Name

* tag name = `link`
* `rel` attr = `icon`, `shortcut icon`
* `href` attr = Website icon filename, relative path, or full path
* Note: The favicon is loaded as soon as the browsers parses the link rel="icon" declaration, or after the page is loaded when the link is not found
* Note: The icon keyword may be preceded by the keyword "shortcut". If the "shortcut" keyword is present, the rel attribute's entire value must be an ASCII case-insensitive match for the string "shortcut icon" (with a single U+0020 SPACE character between the tokens and no other ASCII whitespace).

<<ext "MathiasBynens Rel Icon">>

<<ext "WHATWg.org Link Icon">>

!! Sample code

```
<link rel="shortcut icon" href="favicon.ico">
```

Instapaper

DOC
<<glbl_article_list>>

Instapaper\Export as CSV

Extract FileSystem Service
"""
[https://www.instapaper.com/u]
- [Top-right icon]
- Click login-name menu, option Settings -> Navigates page
- [Settings page, Export section]
- Click link Download .CSV file -> Opens dialog
- Click button OK -> Starts download, closes dialog

[CSV file]
- Header fields =
"""

```
URL
Title
Selection
Folder
Timestamp
```

- Header line =

```
URL,Title,Selection,Folder,Timestamp
```

- Sample data 1 =

```
https://m.youtube.com/watch?v=ABC123DEF&index=14,"""UrQuotedText"" - UrVideoTitle",UrCommentText,"UrInstapaperFolder",1605840648
```

- Sample data 1 =

```
https://www.urcompany.com/urfolder/urarticle/,UrArticleTitle,,UrInstapaperFolder,UrCommentText1603883475
```

Instapaper\Parse file

Text Extract Service
```
\define link_title()
''[<$list filter="[<http_text>split[,]butlast[]last[]]" />]'' <$list filter="[<http_text>split[,]rest[]first[]]" />
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]floor[]]"><$vars tid_year=<<currentTiddler>> >
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]subtract<tid_year>multiply[12]floor[]]"><$vars tid_month=<<currentTiddler>> >
(<<tid_year>>-<<tid_month>>)
</$vars></$list>
</$vars></$list>
<ul>
<$list filter='[<http_text>split[,]butlast[]butlast[]butfirst[]butfirst[]join[,]split["]butfirst[]butlast[]join["]split[""]join["]split[...]]'>
<li><<currentTiddler>></li>
</$list>
</ul>
\end
<$list filter="[{WebNotes\Data}split[http]count[]]" ><$vars total_count=<<currentTiddler>> >Count of entries: <<total_count>><br><br>
<!--
<$button>
<$action-setfield $tiddler="$:/state/popup/audit_1k" text="0"/>
Reset
</$button><br>

<$button>
<$list filter="[{$:/state/popup/audit_1k}add[1000]]">
<$action-setfield $tiddler="$:/state/popup/audit_1k" text=<<currentTiddler>> />
Next 1k
</$list>
</$button><br>
{{$:/state/popup/audit_1k}}

<$list filter="[{WebNotes\Data}split[http]first{$:/state/popup/audit_1k}last[1000]]"><$vars http_text=<<currentTiddler>> >
-->
<$list filter="[{WebNotes\Data}split[{{]join[-opencurlybrace-]split[http]]"><$vars http_text=<<currentTiddler>> >
<$list filter="[<http_text>split[,]first[]!suffix[URL]addprefix[http]]"><$vars http_link=<<currentTiddler>> >
<$list filter="[all[tiddlers]field:twnote<currentTiddler>count[]match[0]]">
<<http_link>><br>
- <<link_title>> <br>
</$list>
</$vars></$list>
</$vars></$list>
</$vars></$list>
```

IrfanView

DOC
<<glbl_article_list>>

IrfanView\Contact Sheet

WindowsOS Formatting Video
"""
[IrfanView app]
- Open one thumbnail image -> Loads image
- Click the File menu option Thumbnails -> Opens dialog
- [Thumbnails dialog]
- Select all files in the folder
- Click the File menu, option Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

JavaScript

DOC
<<glbl_article_list>>

JavaScript\Comment text

CSSCode Browser FileSystem
!! Place a comment text block inside of a JavaScript program

* tag name = `script`
* `type` attr = `text/javascript`
* Start JavaScript comment text block with forward-slash asterisk ( `/*` )
* End comment text with asterisk forward-slash ( `*/` )
* Start JavaScript comment text line with two forward-slashes ( `//` )

!! Sample code

```
<style type="text/javascript">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>
```

JavaScript\Execute Nameless Function

JavaScriptCode FileSystem UserAction
```
;(
    function() {
        alert('hi');
        }
    )();

JavaScript\Exports object

JavaScriptCode FileSystem
!! Determine if running under Node.JS

* Initially at least, `exports` is a reference to `module.exports`
* If you assign anything to `module.exports`, `exports` is not no longer a reference to it, and exports loses all its power

<<ext "SitePoint Exports Node.JS">>

JavaScript\Invalid Variable Names

JavaScriptCode ErrorHandling AssignVariable
<<ext "JavaScript Strict Mode">>

Strict mode makes assignments which would otherwise silently fail to throw an exception.  For example, NaN is a non-writable global variable. In normal code assigning to NaN does nothing; the developer receives no failure feedback. In strict mode assigning to NaN throws an exception.

```
'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError
```

Strict mode in ECMAScript 2015 forbids setting properties on primitive values. Without strict mode, setting properties is simply ignored (no-op), with strict mode, however, a TypeError is thrown.

```
(function() {
'use strict';

false.true = '';         // TypeError
(14).sailing = 'home';   // TypeError
'with'.you = 'far away'; // TypeError

})();
```

JavaScript\Labels

JavaScriptCode FileSystem CodeLibrary
The labeled statement can be used with break or continue statements.

```
List: 
while(counter < 50)
{
     userInput += userInput;
     counter++;
     if(userInput > 10000)
     {
          break List;
     }
}
```

```
var i = 100, j = 100;
outerloop:
while(i>0) {
  while(j>0) {
   j++

   if(j>50) {
     break outerloop;
   }
  }
i++

}
```

```
loop1:
for (let i = 0; i < 5; i++) {
  if (i === 1) {
    continue loop1;
  }
  str = str + i;
}
```

JavaScript\Logical And/Or

JavaScriptCode Numbers
If a value can be converted to true, the value is so-called truthy. If a value can be converted to false, the value is so-called falsy.

Examples of expressions that can be converted to false are:

* null
* NaN
* 0
* empty string ( ` "" ` or ` '' ` ) or empty template literal ( &#x0060;&#x0060; )
* undefined

The logical OR expression is evaluated left to right, and first truthy returned expression stops evaluation of the remaining expressions

The && operator is executed before the || operator

Note: If you use this operator to provide a default value to some variable, be aware that any falsy value will not be used. If you only need to filter out null or undefined, consider using the nullish coalescing operator ( ` ?? ` )

JavaScript\Multi-line string

JavaScriptCode Text Formatting
It's not a multiline string, it's a one line string split over multiple lines of code that make up a single statement.

Old version uses backslash as a line continuation character:

```
eval(" \
alert('hi'); \
");
```

New version uses backtick character as multi-line string:

WARNING: Not supported by IE

```
eval(`
alert('hi');
`);
```

Use string concatenation instead:

```
eval(
"var v1 = 'hi';" +
"alert(v1);"
);
```


JavaScript\Run in HTML Document

JavaScriptCode HTMLCode UserAction
```
<html>
  <body><script type = "text/javascript">window.onerror=function(msg,url,line){alert("Line number = "+line+"\nMessage:\n\n"+msg)}</script>
    <script type="text/javascript">
alert('hi';
      </script>
    </body>
  </html>

JavaScript\Strict Mode

JavaScriptCode CodeLibrary Text
!! Show strict mode compilation errors on specific scripts or functions

* First statement in script or function: 'use strict'; or "use strict";
* Note: Strict mode applies to entire scripts or to individual functions, not individual block statements enclosed in {} braces within a function
* Note: Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally
* Note: The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it

<<ext "MozillaDeveloper Strict mode">>

!! Sample data

```
"use strict";
mistypeVariable = 17;
```

<<<
Result in Developer Tools, Javascript Console:

```
Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLineNumber
```
<<<

```
<script type="module">
mistypeVariable = 17;
</script>
```

<<<
Result:

```
Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLine
```
<<<

JavaScript\String Escape Codes

JavaScriptCode Text CodeLibrary
"""
Here are all the string escape codes:

\0 The NUL character (\u0000)
\b Backspace (\u0008)
\t Horizontal tab (\u0009)
\n Newline (\u000A)
\v Vertical tab (\u000B)
\f Form feed (\u000C)
\r Carriage return (\u000D)
\" Double quote (\u0022)
\' Apostrophe or single quote (\u0027)
\\ Backslash (\u005C)
\x XX The Latin-1 character specified by the two hexadecimal digits XX
\u XXXX The Unicode character specified by the four hexadecimal digits XXXX

JavaScript\This object

JavaScriptCode CodeLibrary
<<ext "JavaScript This Parameter">>

Functions called via property references get "this" set for them: This is the part that really makes it seem like JavaScript has methods: The "this" reference gets set automagically to the object instance if you call a function via a property reference.

Within that call, use the object in question as "this". Getting the function reference from an object property doesn't link it in any way to the object the property came from. The JavaScript engine treats calls of functions just retrieved from object properties as special and sets up "this" accordingly. Essentially, "this" is just a function argument that's passed into the function as an implicit feature of calling a function via a property reference.

JavaScript gives us the call and apply methods on function instances, with which we can say explicitly what we want "this" to be. If you say myfunction.call(myobject), you're saying "call myfunction and use myobject as 'this'", which is what the property-retrieval stuff does implicitly for you.

`UrObject.UrFunction();`

- equates to -

`UrObject.UrFunction.call(UrObject);`

Everything can be seen as a function.

`window['UrObject']['UrFunction'].call(window['UrObject']);`

Getting the function reference from the property (UrObject.UrFunction) is distinct from the fact we're calling it (call) is distinct from what "this" should be ((UrObject)).

<<ext "JavaScript Closures">>

The interpreter creates a call object for this particular execution of the function and sets some properties on that call object before passing it into the function's code.

* A property called arguments which is an array (of sorts, in most implementations it's not actually an Array object) of the actual arguments we called the function with, plus a callee property which is a reference to the function being called.
* A property for each of the arguments defined by the function declaration. The values of these properties are set to the values passed into the function. If any arguments weren't specified (because JavaScript lets you call functions with however many arguments you want, regardless of the definition), properties for any missing arguments are still created on the call object — with the value undefined.
* A property for every declared variable within the function (e.g., every "var" statement). (These start out with the value undefined.)

```
window.UrFunction(UrObject1, UrObject2);
```

That creates a call object for this execution of updateDisplay that essentially looks like this:

```
call.arguments = [UrObject1, UrObject2]
call.arguments.callee = UrFunction
call.ur_input_parm1 = UrObject1
call.ur_input_parm2 = UrObject2
call.internal_var1 = undefined
```

The use of the call object is implicit, because once the call object is created, it's put at the top of the scope chain for the duration of the function call.

JavaScript\TypeOf Name

JavaScriptCode CodeLibrary Text
!! Get string representing object type

* typeof always returns a string
* Note: typeof operator takes precedence over string concatenation ( ` + ` )
* Note: type a let or const variable in a block before they are declared will throw a ReferenceError

* Undefined, undeclared variable, or unassigned variable = "undefined"
* Boolean(1), !!(1) = "boolean"
* Number('321') , Infinity, NaN = "number"
* Bigint, 321n = "bigint"
* String = "string"
* Symbol = "symbol"
* Function() {}, class UrClassName {},  = "function"
* null, object, {ur_prop_name: ur_prop_value}, [ur_val1, ur_val2, ur_val3], new Date(), /regex/ = "object"

JavaScriptBookmarklets

DOC
<<glbl_article_list>>

JavaScriptBookmarklets\Bibliographic citation

<<ext "ALAorg Citations bookmarklet">>
```
javascript:(function(){var h=document.createElement('div');var t=document.getElementsByTagName('title')[0];var info='<p><strong>Title('+t.innerHTML.length+'):</strong> '+t.innerHTML+'</p>';var m=document.getElementsByTagName('meta');for(var i=0;i < m.length;i++){if(null !==m[i].getAttribute('name')){var c=m[i].getAttribute('content');info+='<p><strong>'+m[i].getAttribute('name')+'('+c.length+'):</strong> '+c+'</p>';}}var lm=document.lastModified;var url=location.href;var d=new Date();var dd=d.getDate();var mm=d.getMonth()+1;var yyyy=d.getFullYear();info+='<p><strong>Citation: </strong>"' + t.innerHTML + '." Last modified '+lm+'. <a target="_blank" href="'+url+'">'+url+'</a> (accessed '+mm+'/'+dd+'/'+yyyy+').</p>';document.body.insertBefore(h,document.body.firstChild);h.innerHTML='<div style="border:1px solid %23888;border-radius:5px;-moz-box-shadow:0 0 5px %23888;-webkit-box-shadow:0 0 5px%23888;box-shadow:0 0 5px %23888;background:%23eee;text-align:left;padding:1em;"><a href="%23" onclick="document.body.removeChild(document.body.firstChild);return false">remove</a>'+info+'</div>';})();

JavaScriptBookmarklets\Clear all CSS

Clears all the CSS Class and Style attributes

```
avascript:(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["module"], factory);
  } else if (typeof exports !== "undefined") {
    factory(module);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod);
    global.clearAllCSS = mod.exports;
  }
})(this, function (module) {
  "use strict";

  var each = Array.prototype.forEach;


  function clearAllCSS(nest_level, cur_elt) {
    var _context2;
    if (!cur_elt) {
        throw new Error("No element specified.");
        }

    var _context;
    (_context = cur_elt.children, each).call(_context, function (child) {
        clearAllCSS(nest_level+1, child);
        });

    while(cur_elt.attributes.length > 0) {
        cur_elt.removeAttribute(cur_elt.attributes[0].name);
        }
    }

  module.exports = clearAllCSS;
});
document.querySelectorAll('iframe,script,noscript').forEach(function(element){if (element!=null){element.parentNode.removeChild(element)}});
clearAllCSS(1, document.body);
if (document.head!=null){document.head.parentNode.removeChild(document.head)};
document.querySelectorAll('link').forEach(function(element){if (element!=null){element.parentNode.removeChild(element)}});
document.body.style.fontSize=prompt("Please enter font multiplier", "2") + "00%";
undefined;

JavaScriptBookmarklets\Convert to Inline CSS

Run this script (it takes a while) and then save the web page. All the CSS properties are specified on each element, so it does not need to load any stylesheets.

<<ext "GitHub LukeHorvat Computed Style to Inline">>

```
avascript:(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["module"], factory);
  } else if (typeof exports !== "undefined") {
    factory(module);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod);
    global.computedStyleToInlineStyle = mod.exports;
  }
})(this, function (module) {
  "use strict";

  var each = Array.prototype.forEach;


  function computedStyleToInlineStyle(nest_level, parent_style, cur_elt) {
    var _context2;
    if (!cur_elt) {
        throw new Error("No element specified.");
        }

    var cur_style = getComputedStyle(cur_elt);
    var _context;
    (_context = cur_elt.children, each).call(_context, function (child) {
        computedStyleToInlineStyle(nest_level+1, cur_style, child);
        });

    var parent_copy = document.createElement("an_unknown_tag");
    if (nest_level > 1) {
        for (var pctr = 0; pctr < parent_style.length; pctr++) {
            var pname = parent_style[pctr];
            var pval = parent_style.getPropertyValue(pname);
            parent_copy.style[pname] = pval;
            }
        }

    var blank_element = document.createElement("an_unknown_tag");
    parent_copy.appendChild(blank_element);
    document.head.appendChild(parent_copy);
    var blank_style = getComputedStyle(blank_element);

    for (var dctr = 0; dctr < blank_style.length; dctr++) {
        if (dctr < cur_style.length) {
            var dname = blank_style[dctr];
            var dval = blank_style.getPropertyValue(dname);
			var cval = cur_style.getPropertyValue(dname);
            if (cval != dval && cur_elt.style[dname] != dval) {
                cur_elt.style[dname] = cval;
                }
            }
        }
    }

  module.exports = computedStyleToInlineStyle;
});
(function(){
	var h = document.createElement('div');
	var t = document.getElementsByTagName('title')[0];
	var cite_remove = '<a href="%23" onclick="document.body.firstChild.style.visibility = \'hidden\';document.body.firstChild.style.height = \'0px\';return false">remove</a>';
	var info = '<p><strong>Title(' + t.innerHTML.length + '):</strong> ' + t.innerHTML + '</p>';
	var m = document.getElementsByTagName('meta');
	for(var i = 0; i < ((m == null) ? 0 : m.length); i++) {
		if(null !== m[i].getAttribute('name') ) {
			var c=m[i].getAttribute('content');
			if (c != null) {info += '<p><strong>' + m[i].getAttribute('name') + '(' + c.length + '):</strong> ' + c + '</p>';}
			}
		}
	
	var lm = document.lastModified;
	var url = location.href;
	var d = new Date();
	var dd = d.getDate();
	var mm = d.getMonth()+1;
	var yyyy = d.getFullYear();
	info += '<p><strong>Citation: </strong>"' + t.innerHTML + '." Last modified ' + lm + '. <a target="_blank" href="' + url + '">' + url + '</a> (accessed ' + mm + '/' + dd + '/' + yyyy + ').</p><p><strong>Filename:</strong> ' + '0'.repeat(4-yyyy.toString().length) + yyyy + 'm'+'0'.repeat(2-mm.toString().length) + mm + 'd' + '0'.repeat(2-dd.toString().length) + dd + ' ' + url.replace('http://','').replace('https://','').replace('file:///','').replaceAll('/','-fslash-') + '.html</p>';
	document.body.insertBefore(h,document.body.firstChild);
	h.innerHTML='<div style="border:1px solid %23888;border-radius:5px;-moz-box-shadow:0 0 5px %23888;-webkit-box-shadow:0 0 5px%23888;box-shadow:0 0 5px %23888;background:%23eee;text-align:left;padding:1em;">' + cite_remove + info + cite_remove + '</div>';
	})();
document.querySelectorAll('iframe,script,noscript').forEach(function(element){element.parentNode.removeChild(element)});
computedStyleToInlineStyle(1, null, document.body);
document.head.parentNode.removeChild(document.head);
document.querySelectorAll('link').forEach(function(element){element.parentNode.removeChild(element)});
alert("done");

JavaScriptBookmarklets\Edit current page

Edit webpage

```
javascript:document.body.contentEditable = 'true'; document.designMode='on'; void 0
```

Editing Done

```
javascript:document.body.contentEditable = 'false'; document.designMode='off'; void 0
```

JavaScriptBookmarklets\Extract iFrame pages

JavaScriptCode HTMLCode Extract FileSystem
```
(function(){ var imgs = document.getElementsByTagName('iframe'),t=[]; for (var i=0, n=imgs.length;i'+ imgs[i].src+''); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract images

JavaScriptCode HTMLCode Extract FileSystem
```
avascript:(function(){ var imgs = document.getElementsByTagName('img'),t=[]; for (var i=0, n=imgs.length;i<n;i++) t.push('<a href="'+imgs[i].src+'"><img src="'+ imgs[i].src+'" width="100"></a>'); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract plain text

JavaScriptCode Extract Text
Copy the HTML body to a new window, so CSS and Javascript are ignored

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML;void(newWindow.focus());}
```

Copy the HTML body to a new window showing the HTML tags, so you can see the HTML code

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/&/g,"&amp;").replace(/</g,"<br>&lt;");void(newWindow.focus());}
```

Copy the HTML body without any HTML tags, so the text is loaded without any HTML or CSS styling

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/<[^>]+>/g, '<br>');void(newWindow.focus());}
```

JavaScriptBookmarklets\Unescape HTML code

```
avascript:document.documentElement.innerHTML='<html><body>'+document.body.innerHTML.replaceAll('&lt;','<').replaceAll('&gt;','>').replaceAll('&amp;','&')+'<\/body><\/html>';

JavaScriptBookmarklets\View HTML Source

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){;newWindow.document.documentElement.innerHTML='<html><head><title>Source of Page<\/title><\/head><body><pre>'+document.documentElement.outerHTML.replaceAll('&','&amp;').replaceAll('<','&lt;')+'<\/pre><\/body><\/html>';newWindow.document.body.contentEditable = 'true'; newWindow.document.designMode='on';void(newWindow.focus());}

JavaScriptBookmarklets\View HTML to TW

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){;newWindow.document.documentElement.innerHTML='<html><head><title>Source of Page<\/title><\/head><body><pre>'+document.documentElement.outerHTML.replaceAll('&','&amp;').replaceAll('<','&lt;').replaceAll('&lt;html','&lt;div').replaceAll('&lt;\/html','&lt;\/div').replaceAll('&lt;body','&lt;div').replaceAll('&lt;\/body','&lt;\/div').replaceAll('position: absolute','position: relative').replaceAll('position: fixed','position: relative').replaceAll('position: flex','position: relative').replaceAll('>remove&lt;\/a>','&gt;&lt\/a&gt;').replaceAll('src="http','src_attr="http').replaceAll('src=\'http','src_attr=\'http')+'<\/pre><\/body><\/html>';newWindow.document.body.contentEditable = 'true'; newWindow.document.designMode='on';void(newWindow.focus());}

keyboard action FontLarge

$:/tags/KeyboardShortcut $:/positivesigner/text-ref
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/fontsize" text="24px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/lineheight" text="30px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize" text="25px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodylineheight" text="34px"/>

keyboard action FontNormal

$:/tags/KeyboardShortcut $:/positivesigner/text-ref
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/fontsize" text="14px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/lineheight" text="20px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize" text="15px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodylineheight" text="24px"/>

keyboard action HomeTiddlers

$:/tags/KeyboardShortcut $:/positivesigner/home-button
<$action-sendmessage $message="tm-home"/>

keyboard action Preview

$:/tags/KeyboardShortcut META
<$list filter="[[$:/state/showeditpreview]get[text]!match[yes]]"><$action-setfield $tiddler="$:/state/showeditpreview" text="yes"/></$list>
<$list filter="[[$:/state/showeditpreview]get[text]match[yes]]"><$action-setfield $tiddler="$:/state/showeditpreview" text="no"/></$list>


keyboard action SaveAllChanges

$:/tags/KeyboardShortcut $:/positivesigner/base-install
\define ExportSaveAll(ur_filename, ur_stamp, ur_save_wiki_extension, ur_save_export_html)
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" filename="WikiMove_$ur_filename$-stamp-$ur_stamp$$ur_save_wiki_extension$"
/>
<$list variable=save_export_html filter="[[$ur_save_export_html$]match[1]]">
<$list variable=save_as_html_path filter="[[$ur_filename$]split[-fslash-src-fslash-]join[-fslash-]addprefix[WikiMove_]addsuffix[-stamp-$ur_stamp$.html]]">
<$action-sendmessage $message="tm-download-file"
$param="$:/core/templates/exporters/StaticRiver" filename=<<save_as_html_path>>
exportFilter="""[all[tiddlers]tag[INDEX]sort[title]][all[tiddlers]!tag[EXT]!tag[INDEX]!tag[META]!tag[MCR]!prefix[Draft of]!is[image]!is[tag]!is[system]sort[title]]"""/>
</$list><!--save_as_html_path-->
</$list><!--save_export_html-->
<$action-sendmessage $message="tm-download-file"
$param="template ExportAllCode" filename="WikiMove_$ur_filename$-stamp-$ur_stamp$.card.txt" />
\end
<$list variable=save_export_html filter="[{$:/info/url/full}suffix[.htm]count[]] [[parm SkipSaveExportHTML]is[tiddler]count[]multiply[-1]] +[sum[]]">
<$list variable=save_wiki_extension filter="[{$:/info/url/full}split[.]last[]addprefix[.]]">
<$list variable=save_as_file_name filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.html]join[]split[.htm]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<save_as_file_name>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> ur_save_wiki_extension=<<save_wiki_extension>> ur_save_export_html=<<save_export_html>> />
</$list><!--save_as_file_name-->
</$list><!--save_wiki_extension-->
</$list><!--save_export_html-->

mcr glbl_article_list

$:/tags/Macro $:/positivesigner/text-ref
\define glbl_article_list()
<ol>
<$list variable=card_prefix filter="[<currentTiddler>addsuffix[\]]">
<$list variable=cur_card filter="[prefix<card_prefix>sort[]]">
<$list variable=disp_name filter="[<cur_card>split[\]butfirst[]join[\]]">
<li><$link to=<<cur_card>> ><<disp_name>></$link></li>
</$list><!--disp_name-->
</$list><!--cur_card-->
</$list><!--card_prefix-->
</ol>
\end
\define glbl_article_checklist()
<$vars cur_card=<<currentTiddler>> >
<<glbl_dt_ddd>>
<$wikify name=cur_date text="""<<now "YYYYm0MMd0DD">>""" >
<$list variable=diff_date filter="[<cur_card>get[match_date]else[]!match<cur_date>]">
<$button>
<$list variable=field_name filter="[<cur_card>fields[]prefix[chk_]]">
<$action-setfield $field=<<field_name>> $value="" />
</$list><!--field_name-->
<$action-setfield match_date=<<cur_date>> />
Clear all checkmarks
</$button>
</$list><!--diff_date-->
</$wikify><!--cur_date-->
<ol>
<$list variable=card_prefix filter="[<cur_card>addsuffix[\]]">
<$list variable=cur_entry filter="[prefix<card_prefix>sort[]]">
<$list variable=disp_name filter="[<cur_entry>split[\]last[]]">
<$list variable=chk_name filter="[<disp_name>addprefix[chk_]split[ ]join[_]lowercase[]]">
<li>
<$checkbox default="no" unchecked="no" checked="yes" tiddler=<<cur_card>> field=<<chk_name>> >
<$link to=<<cur_entry>> ><<disp_name>></$link>
</$checkbox>
</li>
</$list><!--chk_name-->
</$list><!--disp_name-->
</$list><!--cur_card-->
</$list><!--card_prefix-->
</ol>
</$vars>
\end

mcr glbl_code_split

$:/tags/Macro $:/positivesigner/text-ref
\define glbl_code_block(ur_note_pk)
[[$ur_note_pk$]]
<$codeblock code={{$ur_note_pk$}} />
\end
\define glbl_code_linenum(ur_note_pk, ur_skip_count, ur_section_size, ur_disp_linenum)
<div style="clear:both">[[$ur_note_pk$]]</div>
<$list filter="[[$ur_skip_count$]!match[]else[0]]" variable=intSKIP_COUNT>
<$list filter="[[$ur_note_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>count[]]" variable=intLINE_COUNT>
<$list filter="[[$ur_section_size$]!match[]!match[0]else<intLINE_COUNT>]" variable=intSECTION_SIZE>
<$list filter="[range<intSECTION_SIZE>]" variable=intCUR_LINE>
<$list filter="[<intCUR_LINE>subtract[1]]" variable=IntREMOVE_LINE>
<$list filter="[[$ur_note_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>butfirst<IntREMOVE_LINE>first[]]" variable=strCUR_LINE>
<$list filter="[[$ur_disp_linenum$]!match[n]!match[0]]"><div style="float:left"><<intCUR_LINE>></div></$list>
<$codeblock code=<<strCUR_LINE>> />
</$list></$list></$list></$list></$list></$list>
\end
\define glbl_code_split_group(ur_note_pk, ur_skip_count)
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]splitregexp[\u0009]join[__	__]splitregexp[\u0020]join[__ __]splitregexp[\u0022\u0022\u0022]join[&#x0022;&#x0022;&#x0022;]]"><<currentTiddler>>
</$list></$list>
\end
\define glbl_code_split_count(ur_note_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_split_group ur_note_pk="$ur_note_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_split_data()
<$macrocall $name=glbl_code_split_count ur_note_pk=<<source_note_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_split_next_group_disp(ur_rem_counter)
<$list filter="[{$ur_rem_counter$}subtract[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_split_disp(ur_source_note_pk, ur_temp_note_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_note_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to find: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
Source data: [[$ur_source_note_pk$]]<br>
\end
\define glbl_code_split_combine()
$(currentTiddler)$$(str_html_out)$
\end
\define glbl_code_split_init(ur_note_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_note_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]add[1]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_note_pk>> text="" />
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_split(ur_note_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_split_init ur_note_pk="$ur_note_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_note_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_split_disp ur_source_note_pk=<<source_note_pk>> ur_temp_note_pk=<<temp_note_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$wikify name=str_html_out text=<<glbl_code_split_data>> >
        <$list filter="[<temp_note_pk>get[text]else[]]"><$vars combine_html_out=<<glbl_code_split_combine>> >
        <$action-setfield $tiddler=<<temp_note_pk>> text=<<combine_html_out>> />
         </$vars></$list>
        <$macrocall $name=glbl_code_split_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> />
        </$wikify>
      
      Find next 100 lines
      </$button><br>

    <$edit-text tiddler=<<temp_note_pk>> autoHeight=no />
    </$vars>
  </$list>
\end
\define glbl_code_disp_group(ur_note_pk, ur_skip_count)
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u00A0]join[&nbsp;]splitregexp[\u0009]join[&nbsp;&nbsp;&nbsp;&nbsp;]splitregexp[\u0020]join[&nbsp;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]]"><<currentTiddler>><br></$list></$list>
\end
\define glbl_code_disp_count(ur_note_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_note_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_disp_data()
<$macrocall $name=glbl_code_disp_count ur_note_pk=<<source_note_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_disp_next_group_disp(ur_rem_counter, ur_oper)
<$list filter="[{$ur_rem_counter$}$ur_oper$[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_disp_disp(ur_source_note_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_note_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to browse: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
\end
\define glbl_code_disp_init(ur_note_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_disp(ur_note_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_disp_init ur_note_pk="$ur_note_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
[[$ur_note_pk$]]<br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_disp_disp ur_source_note_pk=<<source_note_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="subtract" />
      
      Browse next 100 lines
      </$button><br>
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="add" />
      
      Browse prev 100 lines
      </$button><br>

    <<glbl_code_disp_data>>
    </$vars>
  </$list>
\end

<!--<$macrocall $name=glbl_code_disp ur_note_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_disp "WebNotes\Data 1 >>-->

<!--Does not pass through the \u0009 tab or \u00A0 non-breaking space characters. Chrome highlight and copy puts spaces on the clipboard.-->

<!--[[WebNotes\Data]]-->

<!--<$macrocall $name=glbl_code_split ur_note_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_block "UrNotePK">>-->

<!--<<glbl_code_linenum "UrNotePK" 0 15 n>>-->

mcr glbl_compare_lines

$:/tags/Macro $:/positivesigner/text-ref
\define glbl_compare_lines_results_table(ur_note_pk, ur_second_pk, ur_row_count)
<table><tr>
<th>''Line''</th>
<th>Show text</th>
<th>First Side<br>Second Side</th>
</tr>
<$list filter="[range<intSECOND_COUNT>subtract[1]]" variable="intCUR_ENTRY">
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]]" variable="strFIRST_LINE">
<$list filter="[{$ur_second_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]!match<strFIRST_LINE>]" variable="strSECOND_LINE">
<tr>
<td rowspan=2>

!!<<intCUR_ENTRY>>
</td>
<td>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/CompareTextSection1" text="""<$edit-text tiddler="$:/state/CompareTextLine1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/CompareTextLine1}!match[]else[0]]" variable=intSTART_LINE><$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_note_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_note_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/CompareTextSection1"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strFIRST_LINE>> /></td>
</tr>
<tr>
<td>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/CompareTextSection2" text="""<$edit-text tiddler="$:/state/CompareTextLine2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/CompareTextLine2}!match[]else[0]]" variable=intSTART_LINE>
<$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_second_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_second_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/CompareTextSection2"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strSECOND_LINE>> /></td>
</tr>
</$list></$list></$list>
</table>
\end
\define glbl_compare_lines(ur_note_pk, ur_second_pk)
<$list filter="[{$ur_note_pk$}splitregexp[\n]count[]]" variable="intFIRST_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]]" variable="intSECOND_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]subtract<intFIRST_COUNT>]" variable="intSECOND_EXTRA">

[[$ur_note_pk$]] line count: <<intFIRST_COUNT>>

[[$ur_second_pk$]] line count: <<intSECOND_COUNT>>

''$ur_second_pk$'' excess line count: ''<<intSECOND_EXTRA>>''

<$macrocall $name=glbl_compare_lines_results_table ur_note_pk="$ur_note_pk$" ur_second_pk="$ur_second_pk$" ur_row_count=<<intSECOND_COUNT>> />
</$list>
</$list>
</$list>
\end

<!--
<$edit-text tiddler="$:/state/CompareText1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>
<$edit-text tiddler="$:/state/CompareText2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>

<<glbl_compare_lines "$:/state/CompareText1" "$:/state/CompareText2">>
-->

mcr glbl_dt_ddd

$:/tags/Macro $:/positivesigner/text-ref
\define glbl_dt_ddd()
<div style="clear:right;float:right;background-color:aquamarine;"><<now "YYYYm0MMd0DD DDD pm0hh12\m0mm">></div>
<$list filter="[<currentTiddler>split[Draft of ']join[]split[ ]first[]split[m]join[]split[d]join[]]">
<$view field="title" format="date" template="[UTC]DDD" />
</$list>
\end

mcr glbl_ext

$:/tags/Macro $:/positivesigner/text-ref
\define ext(ur_extnote_pk)
<$list variable=missing_entry filter="[[ext $ur_extnote_pk$]get[text]else[]match[]]">Missing: [$ur_extnote_pk$]
</$list><!--missing_entry-->
<$list variable=prefix_dir filter="[{$:/info/url/full}split[/src/]count[]match[2]then[../]else[]]">
<$list variable=found_entry filter="[[ext $ur_extnote_pk$]get[text]else[]addprefix<prefix_dir>]">
<a target="_blank" href=<<found_entry>> >$ur_extnote_pk$</a><div style="float:right">[[->|ext $ur_extnote_pk$]]</div>
</$list><!--found_entry-->
</$list><!--prefix_dir-->
\end

MicrosoftRemoteDesktop

DOC
<<glbl_article_list>>

MicrosoftRemoteDesktop\Setup PC

WindowsOS AndroidOS UserAction
<<ext "Microsoft RemoteDesktop Enable">>

Panel

$:/positivesigner/text-ref
* https://github.com/settings/tokens
>* If there is an existing personal access token,
>>* Click on the name -> Navigates page
>>* Click button Regenerate Token -> Navigates page
>>* Click button Copy to Clipboard
>* Otherwise create a new token
* https://github.com/settings/tokens/new
>* Note = name of end user and device
>>* Must be unique
>>* Each device should get a different token
>* checkbox "repo" = set
>* Click button Generate token -> Navigates page
>* Click button Copy to Clipboard
!!
* <$link to="$:/ControlPanel" />
>* [Saving tab, GitHub Saver sub-tab]
>* Paste into field "Password, OAUTH token, or personal access token"
>* Close the Control Panel card
!!
* Click button <$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" />
Save Wiki
</$button>
>* Wait a few seconds for the "Saved wiki" notification
>* The token is saved in internal browser storage
>* If you get a "401" error, go back to step 1 to generate a new token

Recent Entries

$:/positivesigner/text-ref
[[Search All Fields]]

[[Tags Count Audit]]

[[View All Cards]]

[[View All Code]]

[[Font Size]]

<<timeline limit:30 format:"YYYY-0MM-0DD">>

Regular Expressions

DOC
<<glbl_article_list>>

Regular Expressions\Explanation

RegExCode CodeLibrary
\define disp_re(ur_list, ur_re)
<$vars re="$ur_re$">
`$ur_list$` matches `$ur_re$`?
<$list variable=ret filter="[[$ur_list$]regexp<re>else[no]]"> -,/<<ret>>\,- </$list>

`$ur_list$` split out `$ur_re$`?
<$list variable=ret filter="[[$ur_list$]splitregexp<re>]"> -,/<<ret>>\,- </$list></$vars>
<!--
disp_re-->
\end
[[TiddlyWiki\Regular Expression]]

<<ext "Regexp Filter with brackets">>

<<<
The code would get complexer ^^[sic]^^ too as "[''''[...]'''']" can't be put directly in the regex in TW. You'd have to do it through a variable. And since "[character class]" is reserved in regex you'd also have to escape square brackets "[\[\]]".
<<<

<<ext "Regular Expression Quantifiers">>

Regular expressions take a string of text, and returns a YES or NO as to whether it matches a character pattern.

You can specify a literal character.

* A letter or series of letters
** <<disp_re "ABC" "B">>
* `\`. is a literal period, because without the \ escape it would have special meaning
** <<disp_re "AA.AA" "\.">>

You can use tokens to specify a kind of character to match.

* `\d` is a numeric digit 0 through 9
** <<disp_re "A2C" "\d">>

* `\D` is any non-numeric digit
** <<disp_re "5A8" "\D">>

* `\s` is a whitespace character; like space, tab, or line feed
** <<disp_re "A C" "\s">>

* `\S` is a non-whitespace character
** <<disp_re "A" "\S">>

* `\W` is a whitespace or punctuation character (non-word character)
** <<disp_re ";" "\W">>

* `\w` is a word character (non-whitespace and non-punctuation character)
** <<disp_re "A" "\w">>

* `.` period is any character
** <<disp_re "A" ".">>

You can get out of having to use the \ escape over a block of text if you prefer to type it out.

* `\QOne. Two. Three.\E`  treats anything between the delimiters as a literal string, like "One. Two. Three."
** Useful to escape metacharacters
** Otherwise the periods would be special characters applied to the one letter before each period
** You can also write it as `One\. Two\. Three\.`

A regex quantifier such as `+` tells the regex engine to match a certain quantity of the character, token or subexpression immediately to its left.

* `A+` the quantifier + applies to A
** <<disp_re "AAABCCC" "B+">>
** <<disp_re "AAABBBCCC" "B+">>
* `A*` the quantifier * applies to A
** <<disp_re "ABBBC" "B*">>
** <<disp_re "AC" "B*">>
* `ABC?` the quantifier `?` applies to the C—not to ABC
** <<disp_re "ABCD" "BC?">>
** <<disp_re "ABD" "BC?">>
* `(?:A|B|C)+` the quantifier + applies to the subexpression
** <<disp_re "ABCD" "(?:B|C)+">>
** <<disp_re "ABD" "(?:B|C)+">>
* `\QA.B.C\E+` is treated as a sequence of literals, so the quantifier only applies to the last character
** This could also be written as `A\.B\.C+`

By default, a quantifier tells the engine to match as many instances of its quantified token or subpattern as possible. This behavior is called greedy.

* `A+` is greedy, and matches all the number characters in a row from the starting point where exists (a number)
** <<disp_re "ABBBCD" "B+">>
* `A+B` is greedy, and matches all the number characters in a row where exists (a letter B after a letter A)
** <<disp_re "ABBBCD" "B+C">>
** <<disp_re "ABBBCD" "(B+)C">>

In contrast to the standard greedy quantifier, which eats up as many instances of the quantified token as possible, a lazy (sometimes called reluctant) quantifier tells the engine to match as few of the quantified tokens as needed.

* `\w*?B` is lazy, and matches as few word characters in a row as needed where exists (a letter B after a word character)
** <<disp_re "+ABCCC+" "\w*?C">>
** <<disp_re "+ABCCC+" "\w*C">>

In contrast to the standard docile quantifier, which gives up characters if needed in order to allow the rest of the pattern to match, a possessive quantifier tells the engine that even if what follows in the pattern fails to match, it will hang on to its characters.

* A++ is possessive—it matches as many characters as needed and never gives any of them back.
** Whereas the regex A+. matches the string AAA, A++. doesn't. At first, the token A++ greedily matches all the A characters in the string. The engine then advances to the next token in the pattern. The dot . fails to match because there are no characters left to match. The engine looks if there is something to backtrack. But A++ is possessive, so it will not give up any characters. There is nothing to backtrack, and the pattern fails. In contrast, with A+., the A+ would have given up the final A, allowing the dot to match.

You can specify a number range of characters to repeat.

* A{2,9} uses two to nine As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
** <<disp_re "+ABCCC+" "C{1,2}">>
** <<disp_re "+ABCCC+" "C{2,2}">>
** <<disp_re "+ABCCC+" "C{2,9}">>
* A{2,} uses two or more As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
** <<disp_re "+ABCCC+" "C{2,}">>

You can use negated character classs to match characters other up to the one you want.

* `^[^\.]*` skips up to first period
** <<disp_re "AB.C.D" "^[^\.]*">>
* `^.*\.` skips up to last period
** <<disp_re "AB.C.D" "^.*\.">>

Tempered Greedy Token Solution

* `A(?:(?!B).)*B` stops at the first B instead of the last B
** <<disp_re "AB.C.DCE" "B(?:(?!C).)*C">>
** <<disp_re "AB.C.DCE" "B.*C">>

* `A(?:(?!C)(?!B).)*B` stops at the first B unless there is a C between the A and B
** <<disp_re "AB.CA" "B(?:(?!D)(?!C).)*C">>
** <<disp_re "AB.CAB.FGHBC" "B(?:(?!D)(?!C).)*C">>
** <<disp_re "AB.CAB.DFGHBC" "B(?:(?!D)(?!C).)*C">>

Search All Fields

$:/positivesigner/text-ref
<$vars search_text_pk="$:/state/popup/SearchAllFields">
<$list variable=show_code_pk filter="[<search_text_pk>addsuffix[-checkShowCode]]">
<$list variable=skip_system_pk filter="[<search_text_pk>addsuffix[-checkSkipSystem]]">
<$edit-text tiddler=<<search_text_pk>> field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler=<<skip_system_pk>>> Skip System </$checkbox><br>
<br>

<$list variable=cur_search_text filter="[<search_text_pk>get[text]addsuffix[(?i)]!match[]]">
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]else[no]]">
<$list variable=cur_skipsystem_text filter="[<skip_system_pk>get[text]else[yes]match[yes]count[]]">

<!--Card titles-->
<$list variable=cur_pk filter="[regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_skipsystem_text>] [<cur_pk>!is[system]count[]] +[sum[]match[1]]">

<$link to=<<cur_pk>> />: title
</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

<!--Card fields-->
<$list variable=cur_pk filter="[!regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_pk>is[system]count[]multiply<cur_skipsystem_text>match[0]]">
<$list variable=cur_field filter="[<cur_pk>fields[]]">
<$list variable=found_field filter="[<cur_pk>get<cur_field>regexp<cur_search_text>]">

<$link to=<<cur_pk>> />: <<cur_field>>
<$list variable=disp_code filter="[<cur_showcode_text>match[yes]]">
<$codeblock code=<<found_field>> />
</$list><!--disp_code-->
</$list><!--found_field-->
</$list><!--cur_field-->

</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

</$list><!--cur_skipsystem_text-->
</$list><!--cur_showcode_text-->
</$list><!--cur_search_text-->
</$list><!--skip_system_pk-->
</$list><!--show_code_pk-->
</$vars><!--search_text_pk-->

SQLite

DOC
<<glbl_article_list>>

SQLite\Blob text

SQLCode AssignVariable Filter
<<ext "SQLite Blob text">>

```
WITH RECURSIVE test(c,cur) as (
     SELECT '', HEX(blob_field) FROM UrTable WHERE UrPK = 6
   UNION ALL
    select c || char((case substr(cur,1,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,1,1) end)*16
               + (case substr(cur,2,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,2,1) end)),
substr(cur,3)
from test where length(cur)>0
)
select * from test
```

SQLite\Database Browser

SQLCode FileSystem Extract WindowsOS
<<ext "SQLite DB Browser">>

I used `DB Browser for SQLite - .zip (no installer) for 64-bit Windows`

SQLite\Information Schema

SQLCode FileSystem Extract
<<ext "SQLite schema information">>

```
SELECT name, sql FROM sqlite_master
WHERE type='table'
ORDER BY name;
```

<<ext "SQLite Language functions">>

sqlite_source_id()

```
--version string of SQLite Library source code
2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f
```

sqlite_version()

```
--version string of SQLite Library running
3.33.0
```

SQLite\String Manipulation

SQLCode Extract Text
<<ext "SQLite Language functions">>

```
--comment
```

CHAR(unicode_char_list)

COALESCE(field_list)

HEX(field)

IFNULL(field, default_text)

INSTR(field, search_text)

LENGTH(field)

LIKE(field, comparison_text)

* field LIKE comparisontext
* LIKE(field, comparison_text, escape_char)

LOWER(field)

LTRIM(field)

* LTRIM(field, chars_to_remove)

PRINTF(format_text, field_list)

REPLACE(field, search_text, new_text)

RTRIM(field)

* RTRIM(field, chars_to_remove)

SUBSTR(field, start_char)

* SUBSTR(field, start_char, char_count)

TRIM(field)

* TRIM(field, chars_to_remove)

typeof(field)

* "null", "integer", "real", "text", or "blob".

UNICODE(number)

UPPER(field)

SQLite\Top or Limit records

SQLCode Numbers Filter
<<ext "SQLite Top 5 Records">>

SELECT * FROM Table_Name LIMIT 5;

Tags Count Audit

$:/positivesigner/text-ref
<$list variable=cur_card filter="[!has[tags]!prefix[$:]]">

<$link to=<<cur_card>> />
</$list><!--cur_card-->

---
<$list variable=cur_card filter="[!tag[DOC]!tag[EXT]!tag[IMG]!tag[INDEX]!tag[META]has[tags]!prefix[$:]]">
<$list variable=filter_tag_count filter="[<cur_card>tags[]butfirst[]first[]count[]match[0]]">

<$link to=<<cur_card>> />
</$list><!--filter_tag_count-->
</$list><!--cur_card-->

template ExportAllCode

$:/tags/Exporter $:/positivesigner/base-install
\define renderContent()
<$list variable=cur_tip_pk filter="[all[tiddlers]!has[draft.of]!is[image]has[tags]!prefix[undefined]] [!prefix[$]!has[draft.of]!is[image]!has[tags]!prefix[undefined]] +[sort[title]]">
<hr>
<h2><$link to=<<cur_tip_pk>> /></h2>
<$list variable=cur_tip_text filter="[<cur_tip_pk>get[text]]">
<$codeblock code=<<cur_tip_text>> />
</$list><!--cur_tip_text-->
</$list><!--cur_tip_pk-->
\end
<<renderContent>>

template Home Button

$:/tags/ViewTemplate $:/positivesigner/home-button
<$list variable=on_twcard filter="[<tv-config-toolbar-icons>!match[no]]">
<div style="float:right;padding-left:30px;">
{{$:/core/ui/TopBar/menu}}
</div>

<div style="float:right"><$button set="$:/state/sidebar" setTo="no" tooltip={{$:/language/Buttons/Home/Hint}} aria-label={{$:/language/Buttons/Home/Caption}} class=<<tv-config-toolbar-class>>>
<span class="tc-dirty-indicator">
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/home-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Home/Caption}}/></span>
</$list>
</span>
<$action-sendmessage $message="tm-home"/>
</$button></div>
</$list><!--on_twcard-->

TiddlyWiki

DOC
<<glbl_article_list>>

TiddlyWiki\Add Tag to All Cards

TWCard AssignVariable FileSystem
```
<$button>
<$action-setfield $tiddler="Test1" tags="COPY"/>
Reset Test1 Card's Tag list with just COPY
</$button>

<$button>
<$list variable=cur_card filter="[is[tiddler]!prefix[$:/state/]]">
<$list variable=has_tag filter="[<cur_card>tags[]count[]!match[0]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[append[COPY]]"/>
</$list>
</$list>
Append COPY tag to all Cards that already have tags
</$button>

<$button>
<$list variable=cur_card filter="[tag[COPY]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[remove[COPY]]"/>
</$list>
Remove COPY tag from all Cards
</$button>

TiddlyWiki\Backlink to HTML,HTM

TWCard FileSystem CodeLibrary
Title = ext TW Return

```
\define TW_Return(ur_url, ur_link_title)
<div style="float:right"><a href="$ur_url$"> ($ur_link_title$)</a></div>
\end
<$list filter="[<tv-config-toolbar-icons>match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="TiddlyWiki view of website" />
</$list>
</$list>
<$list filter="[<tv-config-toolbar-icons>!match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]split[.htm]join[.html]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="Static HTML view of website" />
</$list>
</$list>

TiddlyWiki\Button navigate to Card

TWCard UserAction FileSystem
```
<$vars new_code="Test1">
<$list variable=new_pk filter="[<new_code>addprefix[$:/state/popup/]]">
<$button>
<$action-sendmessage $message="tm-new-tiddler" title=<<new_pk>> tags="OneTag [[Another Tag]]" text=<<now "Today is DDth, MMM YYYY">>/>
Create Code ''<<new_code>>'' and Edit
</$button><br>

<$button>
<$action-setfield $tiddler=<<new_pk>> text="yes"/>
<$action-navigate $to=<<new_pk>>/>
Create Code ''<<new_code>>'' and Show
</$button><br>

<$link to=<<new_pk>> /><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
Close Code: ''<<new_code>>''
</$button><br>

<$list filter="[<currentTiddler>!prefix[Draft of]]" variable=strCARD_PK>
<$button>
<$list filter="[list[$:/StoryList]] -[<strCARD_PK>]" variable=strCLOSE_PK>
<$action-sendmessage $message="tm-close-tiddler" $param=<<strCLOSE_PK>>/>
</$list>
Close all other open Codes
</$button>
</$list><br>

<$button>
<$action-sendmessage $message="tm-delete-tiddler" $param=<<new_pk>> />
Delete Card: ''<<new_card>>'' with confirmation
</$button><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
<$action-deletetiddler $tiddler=<<new_pk>> />
Delete Card: ''<<new_card>>'' without confirmation
</$button>
</$list><!--new_pk-->
</$vars><!--new_card-->

TiddlyWiki\Button Set Field

TWCard AssignVariable UserAction
```
<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="yes"/>
Set UrCardPK = yes
</$button>

<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="no"/>
Set UrCardPK = no
</$button>

TiddlyWiki\Checkbox edit

TWCard AssignVariable UserAction
```
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler="$:/state/popup/checkUseIt">Use It</$checkbox>

TiddlyWiki\Clipboard Copy

TWCard AssignVariable UserAction
Tags = `$:/tags/Macro`

```
\define cboard_copy(ur_text)
<pre>$ur_text$</pre>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end
\define cboard_pwd(ur_text ur_pk)
<$reveal type="nomatch" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="show">Show</$button>

</$reveal>
<$reveal type="match" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="hide">Hide</$button>
<pre>$ur_text$</pre>
</$reveal>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end

TiddlyWiki\Code View or Copy data

TWCard CodeLibrary Extract
Title = `mcr glbl_code_split`

Tags = `$:/tags/Macro`

```
\define glbl_code_block(ur_card_pk)
[[$ur_card_pk$]]
<$codeblock code={{$ur_card_pk$}} />
\end
\define glbl_code_linenum(ur_card_pk, ur_skip_count, ur_section_size, ur_disp_linenum)
<div style="clear:both">[[$ur_card_pk$]]</div>
<$list filter="[[$ur_skip_count$]!match[]else[0]]" variable=intSKIP_COUNT>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>count[]]" variable=intLINE_COUNT>
<$list filter="[[$ur_section_size$]!match[]!match[0]else<intLINE_COUNT>]" variable=intSECTION_SIZE>
<$list filter="[range<intSECTION_SIZE>]" variable=intCUR_LINE>
<$list filter="[<intCUR_LINE>subtract[1]]" variable=IntREMOVE_LINE>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>butfirst<IntREMOVE_LINE>first[]]" variable=strCUR_LINE>
<$list filter="[[$ur_disp_linenum$]!match[n]!match[0]]"><div style="float:left"><<intCUR_LINE>></div></$list>
<$codeblock code=<<strCUR_LINE>> />
</$list></$list></$list></$list></$list></$list>
\end
\define glbl_code_split_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]splitregexp[\u0009]join[__	__]splitregexp[\u0020]join[__ __]splitregexp[\u0022\u0022\u0022]join[&#x0022;&#x0022;&#x0022;]]"><<currentTiddler>>
</$list></$list>
\end
\define glbl_code_split_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_split_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_split_data()
<$macrocall $name=glbl_code_split_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_split_next_group_disp(ur_rem_counter)
<$list filter="[{$ur_rem_counter$}subtract[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_split_disp(ur_source_card_pk, ur_temp_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to find: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
Source data: [[$ur_source_card_pk$]]<br>
\end
\define glbl_code_split_combine()
$(currentTiddler)$$(str_html_out)$
\end
\define glbl_code_split_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]add[1]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_card_pk>> text="" />
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_split(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_split_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_split_disp ur_source_card_pk=<<source_card_pk>> ur_temp_card_pk=<<temp_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$wikify name=str_html_out text=<<glbl_code_split_data>> >
        <$list filter="[<temp_card_pk>get[text]else[]]"><$vars combine_html_out=<<glbl_code_split_combine>> >
        <$action-setfield $tiddler=<<temp_card_pk>> text=<<combine_html_out>> />
         </$vars></$list>
        <$macrocall $name=glbl_code_split_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> />
        </$wikify>
      
      Find next 100 lines
      </$button><br>

    <$edit-text tiddler=<<temp_card_pk>> autoHeight=no />
    </$vars>
  </$list>
\end
\define glbl_code_disp_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u00A0]join[&nbsp;]splitregexp[\u0009]join[&nbsp;&nbsp;&nbsp;&nbsp;]splitregexp[\u0020]join[&nbsp;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]]"><<currentTiddler>><br></$list></$list>
\end
\define glbl_code_disp_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_disp_data()
<$macrocall $name=glbl_code_disp_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_disp_next_group_disp(ur_rem_counter, ur_oper)
<$list filter="[{$ur_rem_counter$}$ur_oper$[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_disp_disp(ur_source_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to browse: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
\end
\define glbl_code_disp_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_disp(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_disp_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
[[$ur_card_pk$]]<br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_disp_disp ur_source_card_pk=<<source_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="subtract" />
      
      Browse next 100 lines
      </$button><br>
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="add" />
      
      Browse prev 100 lines
      </$button><br>

    <<glbl_code_disp_data>>
    </$vars>
  </$list>
\end

<!--<$macrocall $name=glbl_code_disp ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_disp "WebNotes\Data 1 >>-->

<!--Does not pass through the \u0009 tab or \u00A0 non-breaking space characters. Chrome highlight and copy puts spaces on the clipboard.-->

<!--[[WebNotes\Data]]-->

<!--<$macrocall $name=glbl_code_split ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_block "UrCardPK">>-->

<!--<<glbl_code_linenum "UrCardPK" 0 15 n>>-->

TiddlyWiki\Codeblock Widget

TWCard Text Formatting CodeLibrary
\define sample_data_e1()
```
sample code "here" and "there"
```
\end

\define sample_data_e2()
<$codeblock code="""sample code "here" and "there"
"""/>
\end

\define sample_data_e3() \define sample_data_e3() sample code "here" and "there"

\define sample_data_e4()
\define sample_data_e4()
sample
code """here"""
and "there"
\end <--Last line of macro
\end

\define sample_data_e5()
<$codeblock code={{{ [[UrCardPK]get[text]] }}}/>
\end

<$codeblock code=<<sample_data_e1>>/>

You can use the `<$codeblock>` widget to display text as the three-backticks TiddlyWiki formatting block. Make sure to put an enter at the end of the string if it ends with d-quotes.

<$codeblock code=<<sample_data_e2>>/>

If you need to show text triple d-quotes in a code string, define a macro to return the string literal instead of passing in a code string.

<$codeblock code=<<sample_data_e3>>/>

Make sure to put a leading space or some trailing comment text on any line within the macro that has `\end` by itself. Otherwise the macro definition will end early.

<$codeblock code=<<sample_data_e4>>/>

Another way to display a Card's content is by using the triple-curly-brace inclusion.

<$codeblock code=<<sample_data_e5>>/>

TiddlyWiki\Compare Lines

TWCard Text Extract Formatting
```
<$diff-text source={{t1}} dest={{mcr glbl_section_disp}}/>
```

Name = mcr glbl_compare_lines

Tag = `$:/tags/Macro`

```
\define glbl_compare_lines_results_table(ur_card_pk, ur_second_pk, ur_row_count)
<table><tr>
<th>''Line''</th>
<th>Show text</th>
<th>First Side<br>Second Side</th>
</tr>
<$list filter="[range<intSECOND_COUNT>subtract[1]]" variable="intCUR_ENTRY">
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]]" variable="strFIRST_LINE">
<$list filter="[{$ur_second_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]!match<strFIRST_LINE>]" variable="strSECOND_LINE">
<tr>
<td rowspan=2>

!!<<intCUR_ENTRY>>
</td>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection1" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine1}!match[]else[0]]" variable=intSTART_LINE><$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_card_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection1"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strFIRST_LINE>> /></td>
</tr>
<tr>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection2" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine2}!match[]else[0]]" variable=intSTART_LINE>
<$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_second_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_second_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection2"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strSECOND_LINE>> /></td>
</tr>
</$list></$list></$list>
</table>
\end
\define glbl_compare_lines(ur_card_pk, ur_second_pk)
<$list filter="[{$ur_card_pk$}splitregexp[\n]count[]]" variable="intFIRST_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]]" variable="intSECOND_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]subtract<intFIRST_COUNT>]" variable="intSECOND_EXTRA">

[[$ur_card_pk$]] line count: <<intFIRST_COUNT>>

[[$ur_second_pk$]] line count: <<intSECOND_COUNT>>

''$ur_second_pk$'' excess line count: ''<<intSECOND_EXTRA>>''

<$macrocall $name=glbl_compare_lines_results_table ur_card_pk="$ur_card_pk$" ur_second_pk="$ur_second_pk$" ur_row_count=<<intSECOND_COUNT>> />
</$list>
</$list>
</$list>
\end

<!--
<$edit-text tiddler="$:/state/popup/CompareText1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>
<$edit-text tiddler="$:/state/popup/CompareText2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>

<<glbl_compare_lines "$:/state/popup/CompareText1" "$:/state/popup/CompareText2">>
-->

TiddlyWiki\Construct a Calendar

TWCard Numbers Formatting Extract
```
\define CalendarEntryDay(ur_ymd,ur_d,ur_cur_date)
<$list filter='$ur_ymd$ +[match[$ur_cur_date$]]'>
//''<span style="background-color:yellow">$ur_ymd$</span>''//<br>
</$list>
<$list filter='[prefix[$ur_ymd$]count[]match[0]]'>
<$list filter='$ur_ymd$ +[!match[$ur_cur_date$]]'>
$ur_ymd$<br>
</$list>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]match[1]]">
''d$ur_d$''<br><<currentTiddler>> entry<br>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]!match[0]!match[1]]">
''d$ur_d$''<br><<currentTiddler>> entries<br>
</$list>
\end

\define CalendarEntryMonth(ur_ym,ur_d,ur_cur_date)
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]!match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d0$ur_d$" ur_d="0$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d$ur_d$" ur_d="$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
\end

\define CalendarListDailyThings(day month year)
<$button class='tc-btn-invisible' style='width:100%;height:100%'>
<div style='height:100%;width:100%;position:relative;text-align:left;vertical-align:top;z-index=0'>

<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]!match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_ym="$year$m0$month$" ur_d="$day$"  ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_m="$year$m$month$" ur_d="$day$" ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>


</div>
</$button>
\end
\define date_list_entry(ur_num,ur_cur_date)
<$list filter="[[$ur_num$]match[$ur_cur_date$]]">
//''<span style="background-color:yellow">$ur_cur_date$</span>''//<br>
</$list>
<$list filter="[prefix[$ur_num$]count[]!match[0]]">
<$list filter="[[$ur_num$]!match[$ur_cur_date$]count[]!match[0]]">
$ur_num$<br>
</$list>
</$list>
<<list-links filter:"[prefix[$ur_num$]]" >>
\end
\define date_list_dayunit(ur_num,ur_cur_date)
<$list filter="$ur_num$0 $ur_num$1 $ur_num$2 $ur_num$3 $ur_num$4 $ur_num$5 $ur_num$6 $ur_num$7 $ur_num$8 $ur_num$9">
<$macrocall $name="date_list_entry" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list_daydec(ur_year_month,ur_num,ur_cur_date)
<$list filter="$ur_year_month$d0 $ur_year_month$d1 $ur_year_month$d2 $ur_year_month$d3 $ur_year_month$d4 $ur_year_month$d5 $ur_year_month$d6 $ur_year_month$d7 $ur_year_month$d8 $ur_year_month$d9">
<$macrocall $name="date_list_dayunit" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list(ur_year,ur_month)
<$calendar-month year="$ur_year$" month="$ur_month$" />

<$macrocall $name="date_list_daydec" ur_year_month="$ur_year$m$ur_month$" ur_num=<<currentTiddler>> ur_cur_date=<<now YYYYm0MMd0DD>> />
\end

TiddlyWiki\Core Macro Definition

TWCard FileSystem Extract
* Title = `mcr glbl_core_mcr_def`
* Tag = `$:/tags/Macro`

```
\define glbl_core_mcr_def(ur_macro_name)
<$list variable=cur_pk filter="""[[$:/core]get[text]split[define $ur_macro_name$(]butfirst[]split[\n\\end]first[]addprefix[define $ur_macro_name$(]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">
<$codeblock code=<<cur_pk>> />
</$list><!--cur_pk-->
\end
```

* Show all Core macro names and source code

```
<$list variable=show_code_pk filter="[<currentTiddler>split[Draft of]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-checkShowCode]]">
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>

<$list variable=cur_def_text filter="[[$:/core]get[text]split[define ]!prefix[{]!prefix[the]sort[]]">
<$list variable=cur_macro_name filter="[<cur_def_text>split[(]first[]]">
<$list variable=cur_end_text filter="""[<cur_def_text>split[\n\\end]first[]addprefix[define ]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">

!! <<cur_macro_name>>
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]match[yes]]"><$codeblock code=<<cur_end_text>> />
</$list><!--cur_showcode_text-->

</$list><!--cur_end_text-->
</$list><!--cur_macro_name-->
</$list><!--cur_def_text-->
</$list><!--show_code_pk-->
```

TiddlyWiki\CSS Classes

TWCard CSSCode Formatting
!! New Card page
* Card name = css alternating-rows
* Tag = $:/tags/Stylesheet

```
.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}
```

Note: The @''''@ directive must include the leading period (.) to select a CSS class

```
@@.alternating-rows
<table>
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

TiddlyWiki\CSS without classes

TWCard CSSCode Formatting
!! Apply stylesheet to all cards

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
.tc-tiddler-body {
  word-break: normal; 
  word-wrap: break-word;
  white-space: pre-wrap;
} 
```

* Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

!! Apply stylesheet to cards with specific tag `linewrap`

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

* Note: Only cards with the `linewrap` tag will use this stylesheet change

!! Apply Styles to In-line Text

* Start a text block with @,,,,@ and the CSS styles with no spaces

Sample Code:

```
@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line
```

<<<
Result:

```
These are
separate lines
here

This is one big line
```
<<<

* or start in the middle of a text block

Sample Code:

```
This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.
```

<<<
Result:

```
This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.
```
<<<

TiddlyWiki\Data Tiddler

TWCard AssignVariable FileSystem
Type = `application/x-tiddler-dictionary`

```
3:a
2:b
3:c
```

See list of unique indexes:

```
<$list variable=cur_key filter="[[UrPK]indexes[]]"><<cur_key>>: 
<$list variable=cur_val filter="[[UrPK]getindex<cur_key>]"><<cur_val>><br>
</$list><!--cur_val-->
</$list><!--cur_key-->
```

Use one value (last one if an index is duplicated):

```
-{{UrPK##3}}-


```

[[VBNetCode\Text file to JSON Lines]]

TiddlyWiki\Date Part

TWCard Numbers Extract Formatting
Tag = `$:/tags/Macro`

```
\define glbl_dt_ddd()
<div style="clear:right;float:right;background-color:aquamarine;"><<now "YYYYm0MMd0DD DDD pm0hh12\m0mm">></div>
<$list filter="[<currentTiddler>split[Draft of ']join[]split[ ]first[]split[m]join[]split[d]join[]]">
<$view field="title" format="date" template="[UTC]DDD" />
</$list>
\end
```

|!Token |!Substituted Value |
|`DDD` |Day of week in full (eg, "Monday") |
|`ddd` |Short day of week (eg, "Mon") |
|`DD` |Day of month |
|`0DD` |Adds a leading zero |
|`DDth` |Adds a suffix |
|`WW` |ISO-8601 week number of year |
|`0WW` |Adds a leading zero |
|`MMM` |Month in full (eg, "July") |
|`mmm` |Short month (eg, "Jul") |
|`MM` |Month number |
|`0MM` |Adds leading zero |
|`YYYY` |Full year |
|`YY` |Two digit year |
|`wYYYY` |Full year with respect to week number |
|`wYY` |Two digit year with respect to week number |
|`hh` |Hours |
|`0hh` |Adds a leading zero |
|`hh12` |Hours in 12 hour clock |
|`0hh12` |Hours in 12 hour clock with leading zero |
|`mm` |Minutes |
|`0mm` |Minutes with leading zero |
|`ss` |Seconds |
|`0ss` |Seconds with leading zero |
|`XXX` |Milliseconds |
|`0XXX` |Milliseconds with leading zero |
|`am` or `pm` |Lower case AM/PM indicator |
|`AM` or `PM` |Upper case AM/PM indicator |
|`TZD` |Timezone offset |
|`\x` |Used to escape a character that would otherwise have special meaning |
|`[UTC]`|Time-shift the represented date to UTC. Must be at very start of format string|

TiddlyWiki\Decimal To Hex

TWCard Numbers Extract
"""
Name = mcr glbl_dec_to_hex5
Tag = `$:/tags/Macro`
"""

```
\define glbl_dec_to_hex5(ur_code)
<$list filter="[[$ur_code$]divide[16]divide[16]divide[16]divide[16]floor[]]" variable=lvl_x4>
<$list filter="[<lvl_x4>multiply[16]multiply[16]multiply[16]multiply[16]]" variable=lvl_d4>
<$list filter="[[$ur_code$]subtract<lvl_d4>divide[16]divide[16]divide[16]floor[]]" variable=lvl_x3>
<$list filter="[<lvl_x3>multiply[16]multiply[16]multiply[16]]" variable=lvl_d3>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>divide[16]divide[16]floor[]]" variable=lvl_x2>
<$list filter="[<lvl_x2>multiply[16]multiply[16]]" variable=lvl_d2>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>divide[16]floor[]]" variable=lvl_x1>
<$list filter="[<lvl_x1>multiply[16]]" variable=lvl_d1>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>subtract<lvl_d1>]" variable=lvl_xrem>
<$list filter="[range[15]butfirst[9]match<lvl_x4>add[55]] [range[10]subtract[1]match<lvl_x4>add[48]]" variable=lvl_h4>
<$list filter="[range[15]butfirst[9]match<lvl_x3>add[55]] [range[10]subtract[1]match<lvl_x3>add[48]]" variable=lvl_h3>
<$list filter="[range[15]butfirst[9]match<lvl_x2>add[55]] [range[10]subtract[1]match<lvl_x2>add[48]]" variable=lvl_h2>
<$list filter="[range[15]butfirst[9]match<lvl_x1>add[55]] [range[10]subtract[1]match<lvl_x1>add[48]]" variable=lvl_h1>
<$list filter="[range[15]butfirst[9]match<lvl_xrem>add[55]] [range[10]subtract[1]match<lvl_xrem>add[48]]" variable=lvl_hrem>
<$wikify name=str_hex_out text="0x&#<<lvl_h4>>;-&#<<lvl_h3>>;&#<<lvl_h2>>;&#<<lvl_h1>>;&#<<lvl_hrem>>;" >
<<str_hex_out>>
</$wikify>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
\end

TiddlyWiki\Delete All Cards with Tag

TWCard FileSystem AssignVariable
```
<$button>
<$list filter="[tag[ARTICLE]]"><$action-sendmessage $message=tm-delete-tiddler $param=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards with Confirmation
</$button>

<$button>
<$list filter="[tag[ARTICLE]]"><$action-deletetiddler $tiddler=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards without Confirmation
</$button>

<$button>
<$list filter="[tag[DOC]]" variable=doc_pk><$list filter="[<doc_pk>fields[]prefix[e]]" variable=field_pk2><$action-deletefield $tiddler=<<doc_pk>> $field=<<field_pk2>> /></$list></$list>
Del fields starting with `E` in DOC tagged Cards
</$button>

TiddlyWiki\DivPop btn

TWCard UserAction FileSystem
[[DivPop.svg]]

Tag = `$:/tags/ViewToolbar`

```
\define divpop_current(ur_ref)
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text="$ur_ref$"/>
<$action-sendmessage $message="tm-close-tiddler" $param="pop_right"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{DivPop.svg}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text="Popup over Sidebar"/></span>
</$list>
</$button>
\end

<$list filter="[all[current]]">
<$macrocall $name=divpop_current ur_ref=<<currentTiddler>> /> 
</$list>

TiddlyWiki\DivPop glbl

TWCard FileSystem UserAction
Tag = `$:/tags/BelowStory`

```
<$list filter="[{$:/state/popup/DivPopTitle}is[tiddler]]">
<div style="
position: fixed;
top: 0px;
right: 0px;
width: 350px;
border: 3px solid;
background: white;
bottom: 0%;
">
<div style="overflow-y: scroll; height: 100%;">
<$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
close
</$button>
<$tiddler tiddler=<<currentTiddler>> >
<$transclude mode="block" />
</$tiddler>
</div>
</div>
</$list>

TiddlyWiki\Embed Font

TWCard Text Formatting FileSystem
"""
[https://tiddlywiki.narkive.com/bS0CgWKQ/tw-tw5-how-to-embed-a-font-using-font-face-and-data-url]
- Visit: http://www.fontsquirrel.com/tools/webfont-generator
- Upload your font file (".ttf", ".eot", ".woff", etc)
- Select option "Expert"
- Check the option case at CSS >> Base64 Encode
- Generate your webkit -> Downloads file

[stylesheet.zip file]
- Unpack ZIP file -> Downloads file

[stylesheet.css]
- Note: The file's content in Base64 encoded

[Wiki file]
- Drag-drop file to import -> Creates Card
- [styleshee.css Card]
- Make sure the field font-family is what you want
- Tag = $:/tags/Stylesheet
- Tiddler type = Plain text (text/plain)
- Create a new Card and use the font

TiddlyWiki\Encrypt file

TWCard FileSystem AssignVariable
"""
[Wiki file]
- [Sidebar, Tools tab]
- Click button Set Password -> Opens dialog
- Password = UrPasswordText
- Repeat password = UrPasswordText
- Click button Set Password -> Closes dialog

[keyboard action SaveAllChanges]
- [<$action-sendmessage $message="tm-download-file"]
- Comment out this tag to keep the HTML Wiki version from being exported
- Save the Wiki file

- Note: The password will be required to start the Wiki application when you open the Wiki file

TiddlyWiki\External Link organization

TWCard FileSystem Formatting
* Create one Card for each external link in this format
** Title always starts with `ext` and a space, then the external link description
** Tagged as EXT
** Contains one line in this format:

```
[ext[ur_url]]
```

* Reference the Card with the `ext` macro, but don't include the `ext` prefix or the leading space
* The link is shown, and there will be `->` on the right side of the Card window
* This flags links that will open in a new tab, and allows you to easily open the `ext` Card and change the saved link

```
<<ext "UrExternalLinkDiscption">>
```

* Global macro
** Title = mcr glbl_ext
** Tag = $:/tags/Macro
** Main Body text =

```
\define ext(ur_extcard_pk)
{{ext $ur_extcard_pk$}}<div style="float:right">[[_|ext $ur_extcard_pk$]]</div>
\end

TiddlyWiki\Filter Operators

TWCard Filter CodeLibrary
!!Math

"""
abs - calculate the absolute value of a list of numbers
add - treating each input title as a number, add to each the numeric value of the operand
ceil - rounds a list of numbers up to the next largest integer
divide - treating each input title as a number, divide them by the numeric value of the operand
exponential - convert each number to exponential notation with N digits
fixed - convert each number to fixed point notation with N digits after the decimal point
floor - rounds a list of numbers to the largest integer less than or equal to each number
max - treating each input title as a number, take the maximum of its value and the numeric value of the operand
maxall - find the largest of a list of numbers
min - treating each input title as a number, take the minimum of its value and the numeric value of the operand
minall - find the smallest of a list of numbers
multiply - treating each input title as a number, multiply it by the numeric value of the operand
negate - calculate the negation of a list of numbers
precision - convert each number to a string with N significant digits
product - produce the product of the input numbers
remainder - treating each input title as a number, return the remainder when divided by the numeric value of the operand
round - rounds a list of numbers to the nearest integer
sign - return -1, 0 or 1 for a list of numbers according to whether each number is negative, zero, or positive
subtract - treating each input title as a number, subtract from each the numeric value of the operand
sum - produce the sum of the input numbers
trunc - truncates a list of numbers to their integer part, removing any fractional part
untrunc - rounds a list of numbers to the next integer with largest absolute value, that is, away from zero

TiddlyWiki\Fonts via URL

TWCard Text Formatting FileSystem
```
<link href='https://fonts.googleapis.com/css?family=Playfair Display' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Sofia' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Alex Brush' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Akronim' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Annie Use Your Telescope' rel='stylesheet'>

@@font-family: 'Playfair Display';
!'Playfair Display'  1234567890 ABC abc
@@

@@font-family: 'Sofia';
!'Sofia'  1234567890 ABC abc
@@

@@font-family: 'Alex Brush';
!'Alex Brush'  1234567890 ABC abc
@@

@@font-family: 'Akronim';
!'Akronim'  1234567890 ABC abc
@@

@@font-family: 'Annie Use Your Telescope';
!'Annie Use Your Telescope'  1234567890 ABC abc
@@

TiddlyWiki\Global Card Footer

TWCard FileSystem Formatting
Every Card shows the Wikified content of the Card content, followed by the Wikified content of every Card with the tag `$:/tags/ViewTemplate`.

!Example Footer Text

Create a new Card

<<<
template Global Footer
<<<

```
Any Text Here
```

Add the tag:

* $:/tags/ViewTemplate

And then every Card will show the words "Any Text Here" at the bottom of the Card.

!Example Footer Home Button

Create a new Card

<<<
template Home Button
<<<

```
<div style="float:right">{{$:/core/ui/Buttons/home}}</div>
```

Add the tag:

* $:/tags/ViewTemplate

And then every Card will show the "Home" icon at the bottom-right of the Card.



TiddlyWiki\Global Macro

TWCard FileSystem
Tag = `$:/tags/Macro`

TiddlyWiki\Group Totals

TWCard CodeLibrary Filter Numbers
```
unique_groups()
- find list of titles with UrAttribute
    - [has[UrAttribute]]
- split by the prefix before the first hyphen
    - [<currentTiddler>split[-]nth[1]]
- return each title's prefix followed by a space
    - ><<currentTiddler>> <

unique_counts()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces
    - [<ugrp>split[ ]
- ignore white-space only entries, and sort the rest alphabetically
    - !match[]sort[]
- use "each:value" to get the unique title prefixes in the list
    - each:value[]]
- for each unique title prefix, get a count of titles with UrAttribute
    - [has[UrAttribute]prefixcount[]]

count_size()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces, ignore white-space, sort, use "each:value", store as ur_entry
    - [<ugrp>split[ ]!match[]sort[]each:value[]]
    - ur_entry=<<currentTiddler>>
- for each unique title prefix, only continue where the count of titles with UrAttribute matches the parent unique count
    - [has[UrAttribute]prefix<ur_entry>count[]match[$(currentTiddler)$]]
- find all the titles with the unique title prefix, and return a "1" for each entry
    - [has[UrAttribute]prefix]">1 <

main()
- create a new variable ucnt with the list of title prefixes from unique_counts()
    - <$wikify name=ucnt text=<<unique_counts>>
- split the new variable by spaces, ignore white-space, sort, use "each:value"
    - [split[ ]trim[]!match[]sort[]each:value[]]
- For each unique count,
    - list the entry
    - sum the number of entries returned from count_size() divided by the unique count
```

```
\define unique_groups()
<$list filter="[has[eng-vocab]]"><$list filter="[<currentTiddler>split[-]nth[1]]"><<currentTiddler>> </$list></$list>
\end
\define unique_counts()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]">
<$list filter="[has[eng-vocab]prefix<currentTiddler>count[]]"><<currentTiddler>> </$list>
</$list>
</$wikify>
\end
\define count_size()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]"><$vars ur_entry=<<currentTiddler>> >
<$list filter="[has[eng-vocab]prefix<ur_entry>count[]match[$(currentTiddler)$]]">
<$list filter="[has[eng-vocab]prefix<ur_entry>]">1 </$list>
</$list>
</$vars></$list>
</$wikify>
\end
<$wikify name=ucnt text=<<unique_counts>> >
<$list filter="[<ucnt>split[ ]trim[]!match[]sort[]each:value[]]">
ASLSJ Prefix Groups with <<currentTiddler>> words -
<$wikify name=usize text=<<count_size>> >
<$list filter="[<usize>split[ ]trim[]!match[]sum[]divide<currentTiddler>]"><<currentTiddler>><br>
</$list>
</$wikify>
</$list>
</$wikify>
```

TiddlyWiki\Hard Line Breaks

TWCard Text Formatting
HTML normally ignores line breaks. TiddlyWiki uses HTML, and includes a way to stop ignoring line breaks.

[TiddlyWiki editor]
- Type three double-quotes (`"""`) and press enter to ignore line breaks below this point
- The (`"""`) does not show up in the output

Three double-quotes will start a hard line breaks section

```
"""
```

```
line one blends into line two continues

"""
line three stops
line four starts
"""
```

line one blends into
line two continues

"""
line three stops
line four starts
"""

!!HTML Preformatted text with Sans-Serif font

`<pre style="font-family: sans-serif;">line three stops
line four starts</pre>`

<pre style="font-family: sans-serif;">line three stops
line four starts</pre>

TiddlyWiki\Hidden on Static File

FileSystem TWCard Formatting
!! Hide section when exported to static HTML file

```
<$list filter="[<tv-config-toolbar-icons>match[no]]">
```

TiddlyWiki\iFrame

TWCard HTMLCode FileSystem Extract
Use an iFrame to run JavaScript in a TiddlyWiki

```
>iframe src="javascript:newWindow='';var ...
```

- just `javascript:newWindow=var ...` did not compile. An empty string is a work-around.

Alternative output: use alert instead of document.write

```
alert(strTEXT);"/>
```

How to reference an external HTML file in a tiddler

```
>iframe src=...  scrolling=yes style="border-style:none;height:100%;width:100%">
>/iframe>
```

- A self-closing tag does not allow remaining html code to be displayed
- ALWAYS specify a closing >/iframe> tag

TW Macro to show iframe and link

```
>div style='float:right'>[ext[_ |$ur_pk$.txt.html]]
>/div>
>iframe src='$ur_pk$.txt.html'>
>/iframe>
```

- $macrocall $name=iframe_txt ur_pk= currentTiddler

```
<iframe src="javascript:newWindow='';var qs = '&quot;';var qt = '&apos;';

var objFRAME = document.createElement('iframe');
objFRAME.setAttribute('id', 'innerFrame');
objFRAME.setAttribute('src', 'http://www.google.com/');
document.body.appendChild(objFRAME); 
var objTEST = objFRAME;
var strTEXT = '';
if (objTEST===undefined) {
strTEXT = 'undef obj';
} else if (objTEST===null) {
strTEXT = 'null obj';
} else {
var intSEQ = 0;
var strNAME;
for (strNAME in objTEST) {
intSEQ += 1;
strTEXT += ' ; ' + strNAME;
}
strTEXT = 'olen ' + intSEQ + strTEXT;
}
document.write(strTEXT);"></iframe>

alert(strTEXT);"/>

<iframe src='iframe.scrE2.txt' height=100% width=100% scrolling=yes frameborder=no></iframe>


\define iframe_txt(ur_pk)
<div style="float:right">[ext[_ |$ur_pk$.txt.html]]</div>
<iframe src='$ur_pk$.txt.html' scrolling=yes style="border-style:none;height:100%;width:100%"></iframe>
\end

TiddlyWiki\Ignore WikiText formatting

TWCard Text Formatting
!! Use the TextWidget to ignore WikiText formatting

* widget name = `$text`
* `text` attr = <$text text="`still black colored text`" />

!! Sample code

```
<$text text="`still black colored text`" />
```

<<<
Results:

<$text text="`still black colored text`" />
<<<
!! Use the Rules card pragma to ignore WikiText formatting

* [New card]
* Put `\rules only` at the top of the card text

!! Sample code

```
\rules only
`still black colored text`
```

<<<
Results:

<$text text="`still black colored text`" />
<<<

!! Use the Card Datatype to ignore WikiText formatting

* [New card]
* `type` field = `text/plain`

!! Sample code

```
`still black colored text`
```

<<<
Results:

```
`still black colored text`
```
<<<

TiddlyWiki\Image

TWCard Formatting
"""
Link an image in a Tiddler with 500px width
- Have image tiddler
- Have text tiddler
- Apply image to text tiddler at 500px width

[New tiddler]
- title = mcr img_link
- tag = $:/tags/Macro
- text field code
"""

```
\define img_link(ur_pk)
@@max-width:500px;
[img [$ur_pk$]]
@@
\end
```

"""
[Text tiddler]
- $macrocall $name=img_link ur_pk= currentTiddler
"""

TiddlyWiki\Image link opens Card

TWCard UserAction FileSystem
Tag = `$:/tags/Macro`

```
\define glbl_image_high(ur_image_pk, ur_size:200)
<$link to="$ur_image_pk$">[img height=$ur_size$px [$ur_image_pk$]]</$link>
\end
\define glbl_image_wide(ur_image_pk, ur_size:500)
<$link to="$ur_image_pk$">[img width=$ur_size$px [$ur_image_pk$]]</$link>
\end

TiddlyWiki\Import Macros

TWCard FileSystem
```
\import [[mcr date_list]]

TiddlyWiki\Javascript Calculation in Bookmarklet

TWCard Bookmarklet Extract JavaScriptCode
* Click the button to copy the text to a javascript bookmarklet
* Open a new tab
* Type the letter "j" in the address bar, paste in the clipboard text, and press enter
* The Javascript alert box shows the message

```
\define glbl_copyto_js_bookmarklet(ur_js_code)
<pre>$ur_js_code$</pre>
<$macrocall $name="copy-to-clipboard" src="""avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){const el = newWindow.document.createElement('textarea');const ur_str='$ur_js_code$';try {el.value =eval(ur_str)}catch(err) {el.value = err.message;}; newWindow.document.body.appendChild(el); el.select();void(newWindow.focus());}""" />
\end

<!--|v
<<glbl_copyto_js_bookmarklet """parseInt("FF",16).toString(10);""">>
^|-->

TiddlyWiki\Keep words together on one line

TWCard Text Formatting
!! Use CSS white-space tag

* The CSS `white-space:nowrap;` disables normal text wrapping
* This is useful when you have several smaller phrases that should not be separated visually onto different lines
* Note: This can make the line extend past the edge of the browser window, requiring scrolling to see the rest

!!Sample Code that can split phrases

```
A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)
```

<<<
Results:

A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)
<<<

!!Sample Code that can keeps short phrases together

```
@@white-space:nowrap;A code line (1)@@ @@white-space:nowrap;A code line (2)@@ @@white-space:nowrap;A code line (3)@@ @@white-space:nowrap;A code line (4)@@ @@white-space:nowrap;A code line (5)@@ @@white-space:nowrap;A code line (6)@@ @@white-space:nowrap;A code line (7)@@ @@white-space:nowrap;A code line (8)@@ @@white-space:nowrap;A code line (9)@@ @@white-space:nowrap;A code line (10)@@ @@white-space:nowrap;A code line (11)@@ @@white-space:nowrap;A code line (12)@@ @@white-space:nowrap;A code line (13)@@ @@white-space:nowrap;A code line (14)@@
```

<<<
Results:

@@white-space:nowrap;A code line (1)@@ @@white-space:nowrap;A code line (2)@@ @@white-space:nowrap;A code line (3)@@ @@white-space:nowrap;A code line (4)@@ @@white-space:nowrap;A code line (5)@@ @@white-space:nowrap;A code line (6)@@ @@white-space:nowrap;A code line (7)@@ @@white-space:nowrap;A code line (8)@@ @@white-space:nowrap;A code line (9)@@ @@white-space:nowrap;A code line (10)@@ @@white-space:nowrap;A code line (11)@@ @@white-space:nowrap;A code line (12)@@ @@white-space:nowrap;A code line (13)@@ @@white-space:nowrap;A code line (14)@@
<<<

TiddlyWiki\Keyboard Shortcut

TWCard CodeLibrary UserAction
!!Pre-requisites

* You need a `ur_message_to_send` to replace in the below steps
** `tm-home` is an example message that TiddlyWiki can do
* You need a `ur_card_pk` to replace in the below steps
** It should describe the desired action

!!Setup keyboard shortcut

[New Card]

* Title = $:/config/ShortcutInfo/ur_card_pk
* Main Body text is blank

[New Card]

* Title = $:/config/shortcuts/ur_card_pk
* Main Body Text =

```
alt-H
```

[New Card]

* Title = keyboard action ur_card_pk
* Tag = $:/tags/KeyboardShortcut
* Field-Value: key =

```
((ur_card_pk))
```

* Main Body Text =

```
<$action-sendmessage $message="ur_message_to_send"/>
```

TiddlyWiki\List Links from Numbered Fields

TWCard Filter Numbers
```
<ol>
<$list filter="[<currentTiddler>fields[]prefix[e]sort[]]" variable=lookup_name>
<$list filter="[<currentTiddler>get<lookup_name>]" variable=ref_card_pk>
<$list filter="[<ref_card_pk>get[img]else[]]" variable=ref_img_pk>
<li><$link to=<<ref_card_pk>> />@@float: right;overflow: auto;vertical-align: top;padding-left: 10px;<$image width=200px source=<<ref_img_pk>> />@@<div style="clear:both;"></div></li>
</$list>
</$list>
</$list>
</ol>

TiddlyWiki\List Links of Prefixed Cards

TWCard Filter
```
<ol>
<$list filter="[<currentTiddler>addsuffix[\]]">
<$list filter="[all[tiddlers]prefix<currentTiddler>sort[]]">
<li><$link to=<<currentTiddler>> /></li>
</$list>
</$list>
</ol>

TiddlyWiki\List Links standard

TWCard Filter
```
<<list-links filter:"[tag[DOC]field:level[1]sort[title]] [tag[DOC]field:level[]sort[title]]">>

TiddlyWiki\List Widget

TWCard Filter
! Content and Attributes

The content of the `<$list>` widget is an optional template to use for rendering each tiddler in the list.

The action of the list widget depends on the results of the filter combined with several options for specifying the template:

* If the filter evaluates to an empty list, the text of the ''emptyMessage'' attribute is rendered, and all other templates are ignored
* Otherwise, if the ''template'' attribute is specified then it is taken as the title of a tiddler to use as a template for rendering each item of the list
* Otherwise, if the list widget content is not blank, it is used as a template for rendering each item of the list
* Otherwise, a default template is used consisting of a `<span>` or `<div>` element wrapped around a link to the item

|!Attribute |!Description |
|filter |The [[tiddler filter|Filters]] to display |
|template |The title of a template tiddler for transcluding each tiddler in the list. When no template is specified, the body of the ListWidget serves as the item template. With no body, a simple link to the tiddler is returned. |
|editTemplate |An alternative template to use for [[DraftTiddlers|DraftMechanism]] in edit mode |
|variable |The name for a [[variable|Variables]] in which the title of each listed tiddler is stored. Defaults to ''currentTiddler'' |
|emptyMessage |Message to be displayed when the list is empty |
|storyview |Optional name of module responsible for animating/processing the list |
|history |The title of the tiddler containing the navigation history |

!! Additional Notes and Edge Cases

* If the `filter` attribute is not present then a default of `[!is[system]sort[title]]` is used
* If the list widget is completely empty (ie only whitespace between the opening and closing tags), then it behaves as if the content were a `DIV` or a `SPAN` containing a link to the current tiddler (it’s a `DIV` if the list widget is in block mode, or a SPAN if it is in inline mode)
* If the `template` attribute is not present then the content of the list widget will be used as the template, unless the widget is completely empty in which case a default template is used

TiddlyWiki\Local Video or Audio Files

TWCard Video Audio FileSystem CodeLibrary
```
<video width="320" height="180"
poster="video\Frozen Sleep - Cortana Tribute by Malukah.png"
controls preload="none">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.webm" type=
"video/webm">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.ogv" type=
"video/ogg">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.mp4" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
```

```
<audio controls preload="none">
<source src="audio\Frozen-Sleep-Malukah.ogg" type="audio/ogg">
<source src="audio\Frozen-Sleep-Malukah.mp3" type="audio/mp3">
<p>Your browser does not support the HTML 5 audio tag.</p>
</audio>
```

TiddlyWiki\Pagination

TWCard Text Formatting Filter
```
\define page_next()
<$list variable="filter_prev_page" filter="[<page_pk>get[text]!match[0]!match[]]">
<$button style="margin-left:30px">
<$action-setfield $tiddler=<<page_pk>> text=""/>
First page
</$button>

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>subtract[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/></$list>
Previous page
</$button>
</$list><!--filter_prev_page-->

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>add[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/><$action-navigate $to=<<card_pk>> $scroll="yes"/></$list>
Next page
</$button><br>
<!--***page_next***-->
\end
<$list variable="card_pk" filter="[<currentTiddler>]">
<$list variable="popup_pk" filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]">

<$list variable="page_pk" filter="[<popup_pk>addsuffix[-cur_page]]">
<$list variable="cur_page_skip" filter="[<page_pk>get[text]!match[]else[0]]">
<$list variable="cur_page_num"filter="[<cur_page_skip>add[1]]">
<$list variable="cur_page_through" filter="[<cur_page_num>subtract[1]add[10]]">
<<page_next>>

<$list variable="subdir_count" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]count[]]">

Subdirectories <<cur_page_num>> through <<cur_page_through>>

Number of subdirectories: <<subdir_count>><br>
<$list variable="cur_subdir_path" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]butfirst<cur_page_num>first[10]]">

<$list variable="raw_image_count" filter="[{File List Data}splitregexp[\n]prefix<cur_subdir_path>uppercase[]suffix[.JPG]count[]addprefix[ (]addprefix<cur_subdir_name>addsuffix[ photo]]">
<<raw_image_count>>
</$list><!--raw_image_count-->

</$list><!--cur_subdir_path-->
</$list><!--subdir_count-->
<<page_next>>
</$list><!--cur_page_through-->
</$list><!--cur_page_num-->
</$list><!--page_pk-->
</$list><!--popup_pk-->
</$list><!--card_pk-->

TiddlyWiki\Popup State Clear All

TWCard CodeLibrary AssignVariable
```
<$list filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]" variable="popup_pk">
<$button>
<$list filter="[all[tiddlers]prefix<popup_pk>has[text]]" variable=del_pk><$action-deletefield $tiddler=<<del_pk>> $field="text"/></$list>
Show All
</$button><br>

</$list>

TiddlyWiki\Published Tools

TWCard CodeLibrary
https://dynalist.io/d/zUP-nIWu2FFoXH-oM7L7d9DM#z=zdF80rIaJ79W5P0IGsjYIjkD

"""
[Ace editor](http://innoq.tiddlyspot.com/)
[ActionIncrement widget](https://skeeve.github.io/tw5-plugins/) - The action-increment widget is an action widget that retrieves a value from a text reference. It will then increase the first digit-sequence found in that text and store it.
[Ad-Hoc Macro](https://tobibeer.github.io/tb5/#Ad-Hoc%20Macro) - evaluate any text as an ad-hoc macro even passing variables.
[Amazon Web Services Plugin](https://tiddlywiki.com/#OfficialPlugins) - provides several tools for working with Amazon Web Services **(official TW plugin)**
[Delay Actions](https://groups.google.com/forum/#!topic/tiddlywiki/z7SGLAPODW8), defer the execution of action widgets for a set amount of time
[CouchDB adaptor](https://github.com/wshallum/couchadaptor)
[Count (tobibeer)](http://tobibeer.github.io/tw5-plugins/#count) - A filter to count titles or compare against a specified count
[Demo Code Macro](http://ooktech.com/jed/ExampleWikis/DemoCodeMacro/) - This is an attempt to make a macro that can be used to demonstrate wikitext code fragments in an interactive way.
[dom (tobibeer)](http://tobibeer.github.io/tw5-plugins/#dom) - retrieve text or attributes from dom nodes
[eval (tobibeer)](http://tobibeer.github.io/tw5-plugins/#eval) - Evaluate expressions, compute and compare tiddler properties and data
[Fargo.io integration](http://blog.jeffreykishner.com/2014/01/24/note-taking-bookmarklets-for-fargoio-and-tiddlywiki-.html)
[Global macros, instructions on how to make](http://tw5magick.tiddlyspot.com/)
[Highlight plugin](https://tiddlywiki.com/plugins/tiddlywiki/highlight/#%24%3A%2Fplugins%2Ftiddlywiki%2Fhighlight) **(official TW plugin)** - description: Plugin that activates syntax highlighting of code blocks using v8.8.0 of highlight.js from Ivan Sagalaev. demo [here](https://tiddlywiki.com/plugins/tiddlywiki/highlight/)
[HTAlink](http://welford.github.io/) - Will only work in offline hta editions of this page. Launches external links in your default browser and not IE
[ifAisB](https://tid.li/tw5/hacks.html) - This macro allows to test if a value A – a variable or a transcluded value – matches a value B and to react accordingly. It works almost like an if-then-else statement.
[IfTid Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the existence of a tiddler (or field) and to send different widget messages based upon the existence of this tiddler (or field.) 
[IfTref Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the value of a TextReference and to send different widget messages based upon whether this value matches the value specified by the 'value=' attribute.
[Incremental load command](http://malsandbox.tiddlyspot.com/) - only loads tiddlers that either don't already exist in the tiddlers folder, or have a newer modified date than the existing tiddler.
[Javascript macros in wikitext](http://tw5magick.tiddlyspot.com/)
[JSON editor (btheado)](http://btheado.github.io/jsoneditor.html)
[JSON editor (bjtools)](http://bjtools.tiddlyspot.com/)
[JsonMangler](https://joshuafontany.github.io/TW5-JsonMangler/) - This plugin changes the methods tiddlywiki uses to retrieve and set values in json data tiddlers. It does this in a way that aims for backwards compatibility.

[keyboard-snippets plugin](http://braintest.tiddlyspot.com/#keyboard-snippets)
[LetWidget](http://tiddlystuff.tiddlyspot.com/) - The LetWidget is an enhancement of the SetWidget.
[mforth](https://quaraman.de/tw/mforth.html) - It is a forth like language in a tiddlywiki macro. Forth operates with Reverse Polish Notation (RPN for short).
[Mousetrap](http://welford.github.io/) - simple library for handling keyboard shortcuts in Javascript.
[muut integration](http://ooktech.com/jed/ExampleWikis/TiddlyWiki-muut/)
[Nodewebkitsaver plugin](http://ooktech.com/jed/ExampleWikis/SetFilters/#%24%3A%2Fplugins%2FOokTech%2FSetFilters) - provides a saver module for saving changes when using [TiddlyWiki](http://ooktech.com/jed/ExampleWikis/SetFilters/#TiddlyWiki) directly under NW.js (previously known as node-webkit).
[Pack as plugin](http://braintest.tiddlyspot.com/#Pack%20as%20plugin) - Beta version
[Pan widget](http://muritest.tiddlyspot.com) - This widget is touch sensitive. It is able to trigger actions as the start and end of pans. Multiple differntial pans are possible.
[Persistent-states](https://wikilabs.github.io/#persistent-states) and [Remove-states](https://wikilabs.github.io/#remove-states)
[pick Plugin](https://skeeve.github.io/tw5-plugins/) - The pick plugin is a set of two filters and one widget to help extracting data from your TiddlyWiki file.
[PluginSize](https://tid.li/tw5/plugins.html#%24%3A%2Fplugins%2Ftelmiger%2FPluginSize:%24%3A%2Fplugins%2Ftelmiger%2FPluginSize) - This plugin calculates the size of all installed plugins, including themes and languages.
[PluginDevelopment](https://github.com/inmysocks/PluginDevelopment) -- Scripts to help you create plugins and plugin libraries for node.js
[pv5](http://pv5.tiddlyspot.com/) - testing params and variables
[random (tobibeer)](http://tobibeer.github.io/tw5-plugins/#random) - A filter to return one or more random titles
[ReplacePragma](http://tiddlystuff.tiddlyspot.com/)
[Save trail plugin](https://tiddlywiki.com/#OfficialPlugins) - This plugin causes TiddlyWiki to continuously download (as a JSON file) the contents of any tiddler that is manually changed by any of several means **(official TW plugin)**
[setvars (tobibeer)](http://tobibeer.github.io/tw5-plugins/#setvars) - Set multiple, complex variables based on attributes, filters, or conditionals
[Shuffle filter operator](https://mklauber.github.io/tw5-plugins/#Shuffle%20Operator) - implements a new filter operator called Shuffle. This operator takes the input list and randomizes the order of the list. If no parameter is provided, the list order is random every time.
[SPilot4Tw](https://www.quaraman.de/tw/pilot.html) - A programming language that can be included as Tiddlywiki plugin.
[Startup Actions demo](http://ooktech.com/jed/ExampleWikis/StartupActions/) - A plugin to add startup scripts to TiddlyWiki 
[style (tobibeer)](http://tobibeer.github.io/tw/style/#GettingStarted) - This wiki introduces you to using your desktop browser to inspect the styles applied to elements in TiddlyWiki and permanently change them.
[Three.js](http://rboue.tiddlyspot.com/#Three.js%2Fintroduction) - 3D modeling
[TiddlyWiki5 Coding](http://cjhunt.github.io/) - These pages document aspects TiddlyWiki5 programming, sharing "lessons learned" to help developers to get started with TiddlyWiki5 customization and extension. (FYI - 4 years old)
[Tinka](https://tinkaplugin.github.io/) - Create and modify plugins in the browser. 
[Trace-variable example](http://eucaly-tw5.tiddlyspot.com/#trace-variable%20Example) - no clue what this is.
[Trigger Actions Demo](http://ooktech.com/jed/ExampleWikis/TriggerActions/)
[Tutorial Maker with HopScotchjs](https://cdn.rawgit.com/abesamma/TW5-tutorial-maker-plugin/29c31124/Demo.html) - a plugin that allows TW5 developers to create interactive product tutorials for their tiddlywiki projects, to guide new users.
[TW Components](https://tw-scripts.github.io/TW-Components/) - A component is a group of TW macros and tiddlers create a visual element for complex processes. The ultimate objective of TW components is to create objects which can simply by used by TW programmer to create complex plugins or codes.
[twexe - run exe's from hta files](https://github.com/welford/twexe) - only works in offline hta versions of TW. It lets you register and run exes from tiddlywiki

TiddlyWiki\Recently Changed Cards

TWCard CodeLibrary Filter
```
<<timeline limit:30 format:"YYYY-0MM-0DD">>

TiddlyWiki\Regular Expression

TWCard Text Filter
```
<!--|v
Split at Regular Expression skips everything before the first period -> `.12`,  `.1` and `.or.maybe.1`
^|-->

<$vars re="^[^\.]*">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>

<!--|v
Split at Regular Expression skips everything before the last period -> `1`,  `1` and `1`

Each:Value gets the unique list of entries -> `2` and `1`

Sort orders them numberically
^|-->

<$vars re="^.*\.">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>!match[]each:value[]sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>


<!--|v
Split
^|-->

<!--<$vars re="^[^\.]*"> skip up to first period excluded-->
<!--<$vars re="^.*\."> skip up to first period included-->
<$vars card_pk="File List Data" re="^.*\.">
<$list variable="cur_file_ext" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.gif(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.jpeg(?i)]] [<card_pk>get[text]splitregexp[\n]regexp[\.jpg$(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.png(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.tif(?i)]] +[splitregexp<re>!match[]each:value[]sort[]addprefix[.]]">
<$list variable="file_ext_count" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]suffix<cur_file_ext>count[]]">

<<cur_file_ext>>: <<file_ext_count>> files
</$list><!--file_ext_count-->
</$list><!--cur_file_ext-->
</$vars>

TiddlyWiki\Reveal Section and Copy Data

TWCard Text Formatting AssignVariable
Title = mcr T1Reveal

```
\define t1cb(UrContent)
<$list filter="[[$UrContent$]!match[]]">
$UrContent$
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
\end
\define t1reveal(UrPK UrSeq UrContent)
<$list filter="[[$UrContent$]!match[]]">
<br>
<$reveal type="nomatch" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="show">,,$UrSeq$,,</$button>
</$reveal>
<$reveal type="match" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="hide">^^$UrSeq$^^</$button><br>
"""
$UrContent$
"""
</$reveal>
<$list filter="[[$UrSeq$]match[Pwd]]">
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
</$list>
\end

TiddlyWiki\Save Wiki and Export HTML

TWCard CodeLibrary Extract Browser
```
\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.htm"
/>
<$action-sendmessage $message="tm-download-file"
$param="$:/core/templates/exporters/StaticRiver" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
exportFilter="""[all[tiddlers]tag[INDEX]sort[title]][all[tiddlers]!tag[EXTLINK]!tag[INDEX]!tag[META]!prefix[Draft of]!is[image]!is[tag]!is[system]sort[title]]"""/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.htm]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>

TiddlyWiki\Search all Fields

TWCard Text Filter
```
<$vars search_text_pk="$:/state/popup/SearchAllFields">
<$list variable=show_code_pk filter="[<search_text_pk>addsuffix[-checkShowCode]]">
<$list variable=skip_system_pk filter="[<search_text_pk>addsuffix[-checkSkipSystem]]">
<$edit-text tiddler=<<search_text_pk>> field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler=<<skip_system_pk>>> Skip System </$checkbox><br>
<br>

<$list variable=cur_search_text filter="[<search_text_pk>get[text]addsuffix[(?i)]!match[]]">
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]else[no]]">
<$list variable=cur_skipsystem_text filter="[<skip_system_pk>get[text]else[yes]match[yes]count[]]">

<!--Card titles-->
<$list variable=cur_pk filter="[regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_skipsystem_text>] [<cur_pk>!is[system]count[]] +[sum[]match[1]]">

<$link to=<<cur_pk>> />: title
</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

<!--Card fields-->
<$list variable=cur_pk filter="[!regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_pk>is[system]count[]multiply<cur_skipsystem_text>match[0]]">
<$list variable=cur_field filter="[<cur_pk>fields[]]">
<$list variable=found_field filter="[<cur_pk>get<cur_field>regexp<cur_search_text>]">

<$link to=<<cur_pk>> />: <<cur_field>>
<$list variable=disp_code filter="[<cur_showcode_text>match[yes]]">
<$codeblock code=<<found_field>> />
</$list><!--disp_code-->
</$list><!--found_field-->
</$list><!--cur_field-->

</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

</$list><!--cur_skipsystem_text-->
</$list><!--cur_showcode_text-->
</$list><!--cur_search_text-->
</$list><!--skip_system_pk-->
</$list><!--show_code_pk-->
</$vars><!--search_text_pk-->

TiddlyWiki\Section Display

TWCard Text Formatting
Card name = `mcr glbl_section_disp`

Tag = `$:/tags/Macro`

```
\define glbl_section_disp(ur_title, ur_section_num)
<$reveal type="nomatch" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="show">

!!$ur_title$ - Show
</$button></$reveal>
<$reveal type="match" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">

!!$ur_title$
</$button><br>

<<section$ur_section_num$>>

<$button style="float:right" class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">
---
</$button><br>
</$reveal>
\end
<!--|v
-- Card content call

\define section1()

section content

!!!here

\end
<<glbl_section_disp "Section 1" 1>>
^|-->

TiddlyWiki\Source Code Samples

TWCard CodeLibrary
!!TiddlyWiki Git repository sample code

[Home button]
<<ext "Tiddly Wiki Home Button source code">>

```
{{$:/core/images/home-button}}
```

<<<
{{$:/core/images/home-button}}
<<<


[Save button]
<<ext "TiddlyWiki Save Button source code">>

```
<$action-sendmessage $message="tm-save-wiki" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>
```

* This code says I can specify my own download file name

```
<span class="tc-dirty-indicator">
```

* This code changes the color of elements within the `<span>` to red when the Wiki file has not been saved

[TiddlyWiki TopBar Menu]

<<ext "TiddlyWiki TopBar Menu">>

```
<$button set="$:/state/sidebar" setTo="no"/>
<$button set="$:/state/sidebar" setTo="yes"/>
```

* These lines show that the `$:/state/sidebar` Card is "no" to hide the sidebar, or "yes" show it

TiddlyWiki\Split Lines into Storage

TWCard Text AssignVariable
```
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>fields:exclude[created title modified]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<new_line_pk>> $field=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:25px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Temp Table

TWCard CodeLibrary AssignVariable
```
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>indexes[]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<ttbLINE>> $index=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:200px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$link to=<<ttbLINE>> />
<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Text Differences

TWCard Text Extract
```
<$diff-text source={{FirstTiddler}} dest={{SecondTiddler}}/>

TiddlyWiki\Textbox field

TWCard AssignVariable
\define sample_data_e1()
<$edit-text tiddler="$:/state/popup/TestText1" field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
\end

\define sample_data_e2()
<$edit-text tiddler="$:/state/popup/TestText2" field=text default="here" placeholder="[no text yet]" autoHeight=yes tag=textarea/>
\end

You can choose to edit a Card or a Card's field in a single-line or multi-line textbox.

* The `default` parameter is automatically placed in the textbox when the Card does not exist
** Typing in the box will add to the default text
** The Card will be created when the text in the box is changed
** Otherwise the default text will not be saved

* The `placeholder` parameter is shown as greyed-out text when the Card does not exist and there is no default text, or the Card exists and the text field is empty
** Typing in the box will overwrite the placeholder text

Note: Editing a Card PK that starts with `$:/state/popup/` will not be saved and does not affect the Wiki's "dirty" flag

[[$:/state/popup/TestText1]]
<$codeblock code=<<sample_data_e1>> />
<<sample_data_e1>>

---
[[$:/state/popup/TestText2]]
<$codeblock code=<<sample_data_e2>> />
<<sample_data_e2>>

TiddlyWiki\TiddlySaver from Downloads

TWCard FileSystem WindowsOS
Make a small form with a timer that moves downloaded TiddlyWiki files back to their original folder

- I have not tried to play around with running TW5 on Node.js. I don't prefer having to use TiddlyDesktop as a separate web browser. Installing a plugin would only save my wiki changes under the downloads directory. I like using a portable web browser on my thumb drive, and I am able to run non-admin programs on my computer. So I made a small program with a timer to move each saved TW file from my Downloads directory back to its original loading location.

- I leave the program running all the time I am logged in. Alt-S saves the data in TiddlyWiki to the Downloads folder. After at most five seconds, the timer moves the file to overwrite the original location. The form flashes on the screen for one second and then hides itself until another move.

1) I created an alt-S shortcut macro to save the current wiki with a specific filename prefix (TWMove_), the entire file path - with substitutions for path-specific characters (: and \), and a time stamp. (Using split/join is accurate enough for me.)

Example: TWMove_C-colon-slash-RootDirOne-slash-SubDirTwo-slash-UrWiki.html

```

\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.html]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>
```

2) I have my web browser save all downloaded files to a specific Downloads folder. (Specifically on Google Chrome, I did install a plugin to automatically hide the dowloaded files bar. It was getting annoying.)

3) I created a small program with a multi-line textbox, and a timer to poll the Downloads folder every five seconds. It moves all the TWMove files in alphabetical order, so the latest timestamped file will be processed last. It finds the destination path as part of the filename. (Moving assumes the original TW.html file is not locked by the browser. This happened to me once, but I just had to restart the browser to release the file lock.)

The program's text box shows the folder I'm polling. When it picks up a file, the original path is pre-pended to the textbox's list of processed files and the form flashes in the foreground for a second. (I could have made a system tray pop-up notification instead.)

It's not perfect, but definitely doable for most amateur programmers.

TiddlyWiki\Transclude Card Field

TWCard Text Extract
```
<$transclude mode="block" tiddler=<<currentTiddler>> />

<$transclude mode="inline" tiddler=<<currentTiddler>> field="ref_data" />

TiddlyWiki\Unicode Character List

TWCard Unicode CodeLibrary
```
\define CharRef(ur_code, ur_line_grouping)
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]floor[]] " variable=div_val>
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]match<div_val>] "><br><sub>$ur_code$
<<glbl_dec_to_hex5 "$ur_code$">>
</sub><br>
</$list>
</$list>
[&#$ur_code$;]
\end

https://en.wikipedia.org/wiki/Unicode_block

https://en.wikipedia.org/wiki/Plane_(Unicode)


<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text=""/>
Line Grouping = 10
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text="16"/>
Line Grouping = 16
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text=""/>
Clear selection
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="0"/>
Show Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="65536"/>
Show Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="131072"/>
Show Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="196608"/>
Show Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)
</$button>

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

@@font-family: "Lucida Console", Courier, monospace;
<$list filter="[{$:/state/mcr CharRef LineGrouping}!match[]else[10]] " variable=line_grouping>
<$list filter="[[$:/state/mcr CharRef CharacterListBase]get[text]!match[]]">
<$list filter="[range[512]subtract[1]multiply[128]add{$:/state/mcr CharRef CharacterListBase}]" variable=cur_block>
<h2><<cur_block>></h2>
<$list filter="[range[128]subtract[1]] +[add<cur_block>] " variable=cur_code>
<$macrocall $name=CharRef ur_code=<<cur_code>> ur_line_grouping=<<line_grouping>> />
</$list>
</$list>
</$list>
</$list>


TiddlyWiki\Unicode Codepoints Used

TWCard Unicode Extract
```
\define dec_to_u_hex4()
<$list variable=cur_d4 filter="[[$(dec_num)$]divide[16]floor[]divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d4 filter="[[0]subtract<cur_d4>multiply[16]multiply[16]multiply[16]add[$(dec_num)$]]"
><$list variable=cur_d3 filter="[<rem_d4>divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d3 filter="[[0]subtract<cur_d3>multiply[16]multiply[16]add<rem_d4>]"
><$list variable=cur_d2 filter="[<rem_d3>divide[16]floor[]]"
><$list variable=rem_d2 filter="[[0]subtract<cur_d2>multiply[16]add<rem_d3>]"
><$list variable=hex filter="[[;]addsuffix<cur_d4>addsuffix[;]addsuffix<cur_d3>addsuffix[;]addsuffix<cur_d2>addsuffix[;]addsuffix<rem_d2>split[;10]join[A]split[;11]join[B]split[;12]join[C]split[;13]join[D]split[;14]join[E]split[;15]join[F]split[;]join[]]"
>\u<<hex>></$list><!--hex
--></$list><!--rem_d2
--></$list><!--cur_d2
--></$list><!--rem_d3
--></$list><!--cur_d3
--></$list><!--rem_d3
--></$list><!--cur_d4
-->
\end
\define entry_hexcode(ur_char, ur_code_page)
<$list variable=cur_codepage filter="""[[$ur_code_page$]!match[]else[0]multiply[256]]""">
<$list variable=dec_num filter="""[range[256]add<cur_codepage>]""">
<$wikify name=hex_unicode text=<<dec_to_u_hex4>> >
<$list filter="""[[$ur_char$]regexp<hex_unicode>]""" variable=match_text>
-$ur_char$-<<hex_unicode>>-&amp;#<<dec_num>>;
</$list><!--match_text-->
</$wikify><!--hex_unicode-->
</$list><!--cur_unicode-->
</$list><!--cur_unicode-->
\end
\define unicode_points(ur_pk)
<$list variable=code_page filter="[[$:/state/unicode_points_codepage]get[text]else[0]]">

Code page = <<code_page>> <$button

style="margin-left:30px">
<$list variable="next_page" filter="[<code_page>add[1]]"><$action-setfield $tiddler="$:/state/unicode_points_codepage" text=<<next_page>>/></$list>
Next page
</$button><$button

style="margin-left:30px">
<$action-setfield $tiddler="$:/state/unicode_points_codepage" text="0"/>
Reset
</$button><br>


<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]count[]!match[1]!match[0]]">-&#x005D;-\u005D-&amp;#93;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u0060]count[]!match[1]!match[0]]">-&#x0060;-\u0060-&amp;#96;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]join[]splitregexp[\u0060]join[]split[]each:value[]sort[]]">-<<cur_char>>-
<$macrocall $name=entry_hexcode ur_code_page=<<code_page>> ur_char=<<cur_char>> />
<br>
<br>
</$list><!--cur_char-->
</$list><!--code_page-->
\end

<<unicode_points "UrPK">>

TiddlyWiki\Upload File

TWCard FileSystem Extract
!! Drag and drop
* Drag a file icon from the Windows Desktop or Windows Explorer over the Wiki until you see a top-margin green bar show
* Release the mouse to drop the file -> Opens card

!! Import Card
* Review the file list and uncheck and undesired import objects
* Click button Import -> Creates Cards

!! BrowseWidget

* Create a $browse tag -> Makes button
* Click button Choose File -> Opens dialog
* Choose a file -> Closes dialog, opens Card

!! Import Card
* Review the file list and uncheck and undesired import objects
* Click button Import -> Creates Cards

```
<$browse />
```

TiddlyWiki\Video and Audio

TWCard Video Audio
* Title = mcr glbl_ext_av
* Tag = `$:/tags/Macro`
* Note: The paths are relative to the current website. You cannot load Video or Audio content from other websites due to browser restrictions.

* Note: You can add attribute `poster="placeholder.png" ` to the Video tag if you have a specific image you want instead of the video's first frame

```
\define glbl_ext_video(UrFolder,UrVideo,UrTime)
<video width="320" height="180"
controls preload="metadata">
<source src="$UrFolder$/$UrVideo$.mp4#t=$UrTime$" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
\end
\define glbl_ext_audio(UrFolder,UrAudio,UrTime)
<audio controls preload="none">
<source src="$UrFolder$/$UrAudio$.mp3#t=$UrTime$" type=
"audio/mp3">
Your browser does not support the HTML 5 audio tag.
</audio>
\end

<!--|v
* Hard-coded to only use MP4 files

<<glbl_ext_video "MyVideosSubFolder" "MyVideoFile" "00:01:00">>

<<glbl_ext_video "file:///C:/UrFolder/UrSubFolder" "UrFilenameNoExtension" "00:01:00">>
^|-->
<!--|v
<<glbl_ext_audio "MyAudioSubFolder" "MyAudioFile" "00:01:00">>
^|-->

TiddlyWiki\View All Cards

TWCard CodeLibrary Extract
```
<$list filter="[all[tiddlers]!tag[EXTLINK]!tag[IMG]!tag[INDEX]!tag[MCR]!tag[META]!has[draft.of]!is[image]!is[tag]!is[system]has[tags]!prefix[undefined]sort[title]]">
<hr>
<h2><$link to=<<currentTiddler>> /></h2>
{{||$:/core/ui/ViewTemplate/tags}}
<$transclude mode="block"/>
</$list>

TiddlyWiki\Wikify Text

TWCard Extract Text
```
<$wikify name=str_text_out text="&#65;">
A = <<str_text_out>>
</$wikify>

<$wikify name=str_text_out text="''bold font''" output=html>
B = <<str_text_out>>
</$wikify>

TiddlyWiki\WikiText Formatting

TWCard Formatting Text CodeLibrary
You can type most standard text without problems. Leading, repeated, or paired special characters may need escaped.

!Vertical Spacing

```
Pressing enter at the end of a line does not start a new paragraph.
Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph.
Press enter twice.
```

For example, see how the above two paragraphs are shown below:

Pressing enter at the end of a line does not start a new paragraph.
Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph.
Press enter twice.


!Leading Special Characters

!!Bulleted List Entry

```
*Bulleted List Entry
```

*Bulleted List Entry

Leading with an asterisk creates a bulleted list entry. To escape, prefix with four single-quotes.

If you want a single blank line between two bullet points, use a !''''! Heading Line without any title text.

```
''''*Bulleted List Entry
```

''''*Bulleted List Entry

!!Heading Line

```
!Heading Line
```

Starting a new paragraph line with an exclamation mark (!) results in a heading line.

```
!Heading Line
```

The above heading markup starts with an exclamation mark. To escape, prefix with four single-quotes.

```
''''!Heading Line
```

''''!Heading Line

!!Mono-spaced Text Block

```
 ```
 Mono-spaced Text Block
 ```
```

```
Mono-spaced Text Block
```

Leading with a triple back-tick creates a mono-space text block. To escape, surround the triple back-tick with doubled square-brackets.

```
[[''']] Regular typeface
```

[[```]] Regular typeface

!!Numbered List Entry

```
#Numbered List Entry
```

#Numbered List Entry

Leading with a pound-sign creates a numbered list entry. To escape, prefix with four single-quotes.

```
''''#Numbered List Entry
```

''''#Numbered List Entry

!!Quoted text block
```
<<<
Quoted text block
<<<
```

<<<
Quoted text block
<<<

Leading with a triple less-than creates a quoted text block. To escape, surround the 

```
''''<<< Unquoted text
```

''''<<< Unquoted text

!!URL Links

```
https://tiddlywiki.com/
```

https://tiddlywiki.com/

Start text with an "http'''':/''''/" "http'''':/''''/" will create a URL link. To escape, place four single-quotes before the colon and between the double forward-slashes.

```
https'''':/''''/tiddlywiki.com/
```

https'''':/''''/tiddlywiki.com/


!Repeated Special Characters

```
''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`
```

''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`

A number of repeated special characters are used as Wiki Markup to format text. To escape, place four single-quotes between the doubled characters or surround the doubled characters with doubled square-braces.

```
[['']]Bold Text[['']] /''''/Italic Text/''''/ ~''''~Strike-through Text~''''~ _''''_Underlined Text_''''_ ^''''^Raised-Small Text^''''^ ,'''',Lowered-Small Text,'''', [[`]]Mono-spaced Text[[`]]
```

[['']]Bold Text[['']] /''''/Italic Text/''''/ ~''''~Strike-through Text~''''~ _''''_Underlined Text_''''_ ^''''^Raised-Small Text^''''^ ,'''',Lowered-Small Text,'''', [[`]]Mono-spaced Text[[`]]

!Paired Special Characters

!!Literal Text

```
[[Literal Text]]
```

[[Literal Text]]

Surrounding text with doubled square-brackets shows the literal surrounded text without applying formatting. To escape, place four single-quotes between the first doubled square-brackets.

```
[''''[Literal Text]]
```

[''''[Literal Text]]

!!Transcluded Text

```
{{Other Tiddler Title}}

Note: The other tidder's content is "Other Tiddler Transcluded Text".
```

{{Other Tiddler Title}}

Surrounding text with doubled curly-braces shows the full content of another tiddler. To escape, place four single-quotes between the first doubled curly-braces.

```
{''''{Other Tiddler Title}}
```

{''''{Other Tiddler Title}}

!!HTML Markup

```
<b>HTML Markup</b>
```

<b>HTML Markup</b>

Surrounding text with angled-brackets uses HTML formatting. To escape, rename the first angle-bracket to &lt'''';

```
&lt;b>HTML Markup</b>
```

&lt;b>HTML Markup</b>

!!HTML Literals

```
&lt;

Note: &lt; represents a left angle-bracket, or the less-than symbol (<).
```

&lt;

Surrounding text with an ampersand (&) and a semi-colon translate to an HTML literal. To escape, place four single-quotes after the ampersand.

```
&lt;
```

&''''lt;


!!CSS Styles

You can apply CSS styles in-line with the text. Make sure you put the semi-colon at the end of the style list.

```
You can apply @@background-color:yellow; CSS styles @@ in-line with the text.
```

You can apply @@background-color:yellow; CSS styles @@ in-line with the text.


!!Tables

```
|!Cell1 |!Cell2 |
|Cell3 |Cell3 |

|^top left |^ top center |^ top right|
|middle left | middle center | middle right|
|,bottom left |, bottom center |, bottom right|


To merge a table cell with the one above, use the special cell text ~. To merge a cell with the one to its left use the text <. To merge one to its right use >. For example:

|Cell1 |Cell2 |Cell3 |Cell4 |
|Cell5 |Cell6 |Cell7 |<|
|Cell5 |~|Cell7 |Cell8 |
|>|Cell9 |Cell10 |Cell11 |

assigns the CSS classes "myclass" and "anotherClass" to the table
gives the table the caption "This is a caption"
adds a header row of cells with the text "Header"
adds a footer row of cells with the text "Footer"
|myclass anotherClass|k
|This is a caption |c
|Cell1 |Cell2 |
|Cell3 |Cell3 |
|Header|Header|h
|Footer|Footer|f
```

TiddlyWiki\Word Wrap

TWCard Text WordWrap
!! Hard-line breaks using CSS styles

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
.tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

* Note: When using this alternate CSS, wiki text markup will be ignored unless preceded by a double-spaced line
* Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

Sample Code:

```
*bullet 1
*bullet 2
*bullet 3
Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a ",,,,",,,," wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

*bullet 4 requires a preceding double-spaced line to be interpreted as wikitext
```

<<<
Results:

```
* bullet 1
* bullet 2
* bullet 3

Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a """ wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

* bullet 4 requires a preceding double-spaced line to be interpreted as wikitext
```
<<<

!! Apply stylesheet to cards with specific tag `linewrap`

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

!! Apply Styles to In-line Text

* Start a text block with @,,,,@ and the CSS styles with no spaces

Sample Code:

```
@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line
```

<<<
Result:

```
These are
separate lines
here

This is one big line
```
<<<

* or start in the middle of a text block

Sample Code:

```
This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.
```

<<<
Result:

```
This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.
```
<<<

TotalCommander

DOC
<<glbl_article_list>>

TotalCommander\Create new Text File

Text FileSystem AndroidOS
"""
[Total Commander directory]
- [Top of the directory]
- Hold down on the '..' button to see the menu -> Opens menu
- - or Hold down on any subdirectory name to see the menu -> Opens menu

- [context menu]
- Click option New Text file -> Opens dialog

- [Create new text file dialog]
- Enter a new text file name
- Click button OK -> Closes dialog

- [Directory list]
- Note: The new file was added to the current folder

TotalCommander\Local file desktop shortcut

AssignVariable FileSystem AndroidOS
"""
Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Total Commander directory]
- Hold down on file entry named like *.html -> Opens menu

- [context menu]
- Click option Create link on desktop -> Opens dialog

- [Create link dialog, main page, command line section]
- Click button '>>' -> Opens dialog

- [Choose app dialog, main page]
- Click option Choose app * -> Navigates page

- [Choose app dialog, Choose app * page]
- Click option Chrome -> Navigates page

- [Create link dialog, main page]
- Click button OK / Apply -> Closes dialog

[Android Desktop icons]
- Note: The icon was added to the desktop automatically

TW Project

DOC
<<glbl_article_list>>

TW Project\Check app

TWCard CodeLibrary
<<ext "Project Check app">>

Goal: Find food by aisle

TW Project\Code Snapshot

TWCard CodeLibrary
<<ext "TW Snapshot Review">>

Goal: Browse the code inside the WIki file

<<ext "TW Snapshot v5d01d23 main-site">>

<<ext "TW Snapshot v5d01d23 empty">>

<<ext "TW Snapshot v5d01d23 pre-release">>

<<ext "TW Snapshot v5d01d23 update">>

TW Project\Features list

TWCard CodeLibrary
<<ext "TW Features">>

Goal: Demonstrate every Wiki command and option

TW Project\Javascript Plugin instructions

TWCard JavaScriptCode
<<ext "TW Create Javascript Plugin">>

TW Project\Shuffle List addon

TWCard CodeLibrary Filter
<<ext "Shuffle List Entries">>

TW Project\Text Replace addon

TWCard Text AssignVariable
<<ext "TW Addon Text Replace">>

Goal: Add text replacement functionality to the standard TWCard editor

TW Project\TiddlyWiki Manual

TWCard CodeLibrary
<<ext "TW Manual">>

Goal: Explain the Single-Page Quine Wiki architecture

TW Project\TW JS Pretty

TWCard JavaScriptCode Formatting
<<ext "TW JS Pretty">>

Goal: Upload a text file and comment on each line, table or function

TW Project\Wiki Empty Setup

TWCard HTMLCode Extract
<<ext "Empty Wiki Setup">>

Goal: Use the empty TW document and generate a static HTML page

Unicode

DOC
<<glbl_article_list>>

Unicode\Code Blocks

Unicode Text CodeLibrary
<<ext "Unicode Block 00-Basic Latin">>

<<ext "Unicode Block 01-Latin Supplement">>

<<ext "Unicode Code Block List">>

<<ext "Unicode Block Planes">>

Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)

Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)

Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)

Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

Unicode\Latest Version

Unicode Text CodeLibrary
<<ext "Unicode Character Database">>

All files for the most up-to-date version of the Unicode Character Database can be found at: http://www.unicode.org/Public/UCD/latest/.

The latest text file databases are at https://www.unicode.org/Public/UCD/latest/ucd/. The latest set of text file databases is in a ZIP file at https://www.unicode.org/Public/UCD/latest/ucd/UCD.zip.

The list of Unicode Code Blocks are in the text database https://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt.

There is a list of names for the Unicode Code Points at https://www.unicode.org/Public/UCD/latest/ucd/Index.txt. There same list is sorted in Code Point order at https://www.unicode.org/Public/UCD/latest/ucd/NameAliases.txt. Each hex code can have multiple names.

The unique list of Unicode Code Points is at https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt. There is a character name and possibly an alternative name on each row.


VBNetCode

DOC
<<glbl_article_list>>

VBNetCode\Application Startup require DLLs

CodeLibrary VBCode
```
Option Strict On
Namespace My
    Partial Friend Class MyApplication
        Sub Main(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
            Mx.Want.TestReferencedAssemblies_errhnd(e)
            'Next goes to frmInput_1_Load, then Want.Compile_And_Run_Script
        End Sub
    End Class
End Namespace

Namespace Mx
    Partial Public Class Want
        Public Shared Sub TestReferencedAssemblies_errhnd(ur_startup_event_args As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs)
            Dim objERR_LIST = New ErrListBase : Try
                Call Assistant.TestReferencedAssemblies()

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                MsgBox(objERR_LIST.ToString, , My.Application.Info.Title)
                ur_startup_event_args.Cancel = True
            End If
        End Sub 'TestReferencedAssemblies_errhnd
    End Class 'Want
    
    Partial Public Class Assistant
        Public Shared Sub TestReferencedAssemblies()
            'Will error if DLL does is not available
            Dim objV1 = System.Data.SqlClient.SortOrder.Ascending
        End Sub 'TestReferencedAssemblies
    End Class 'Assistant
End Namespace 'Mx

VBNetCode\Checksum calculate

Numbers Extract VBCode
I want a .Net program to calculate the SHA512 hash of a file

```
Dim strHASH_KEY = ""
Using objSHA = New System.Security.Cryptography.SHA512Managed
    Using stmFILE = System.IO.File.OpenRead(flnDATA)
        strHASH_KEY = "[" & System.BitConverter.ToString(objSHA.ComputeHash(stmFILE)).Replace("-", "").ToLower & "]"
        'Convert.ToBase64String(
    End Using
End Using

VBNetCode\Copy File Lines

FileSystem Extract VBCode
```
Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), bolAPPEND_FILE, gUTF8_FileEncoding)
	Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
		While stmDATA.EndOfStream = False
			'Character copy
			Dim intENTRY = stmDATA.Read()
			Dim strENTRY = ChrW(intENTRY)
			stmOUT_FILE.Write(strENTRY)
			
			'Line copy
			Dim strLINE = stmDATA.ReadLine()
			stmOUT_FILE.WriteLine(strLINE)
		End While 'stmDATA
	End Using 'stmDATA
End Using 'stmOUT_FILE
```

Split File into chunks of 100,000 lines each

```
Dim intFILE_COUNT = 0
Dim intLINE_COUNT = 0
Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
	While stmDATA.EndOfStream = False
		intFILE_COUNT += 1
		intLINE_COUNT = 0
		Dim strFILE_COUNT = intFILE_COUNT.ToString()
		If Len(strFILE_COUNT) = 2 Then
			strFILE_COUNT = "c" & strFILE_COUNT
		ElseIf Len(strFILE_COUNT) = 3 Then
			strFILE_COUNT = "d" & strFILE_COUNT
			
			End If 'strFILE_COUNT
		
		strFILE_COUNT = "e" & strFILE_COUNT
		Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT(strFILE_COUNT & ".TXT"), False, gUTF8_FileEncoding)
			While stmDATA.EndOfStream = False
				Dim strLINE = stmDATA.ReadLine()
				stmOUT_FILE.WriteLine(strLINE)
				intLINE_COUNT += 1
				
				If intLINE_COUNT >= 100000 Then
					Exit While
					
					End If
				
				End While 'stmDATA
			
			End Using 'stmOUT_FILE

		End While 'stmDATA
	
	End Using 'stmDATA

VBNetCode\DotNet Core Compile EXE

Extract VBCode WindowsOS
[https://github.com/dotnet/core/issues/5409]

<<<
In .NET 5 the single-file publish may produce more than one file and it's by design. See the expected behavior described here: 

https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md#user-experience

In 3.1 single-file is basically just a self-extracting executable - it writes everything into temp and runs from there. As such for the running app nothing really changes (everything is a file, with a path and so on).

In 5 we don't write to disk by default, all managed assemblies are loaded directly from the executable. The problem is native libraries - it's technically VERY difficult to include a random .dll in an executable and run it from the executable directly.

If you only take the .exe and run it, it won't work - it needs those additional files.

If you need .NET 5 but want the self-extracting behavior you can set IncludeAllContentForSelfExtract=true and it will behave basically the same as in 3.1.

There's also a "hybrid" mode IncludeNativeLibrariesForSelfExtract=true which will produce just one executable and that will write the native libraries to temp and then run.
<<<

User-replaced value = UrProjectDir

[UrProjectDir folder]
- Start with [[VBNetCode\DotNet Core New Project]]

"""
[Windows CLI]
- [Compile into an EXE]
- `dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep`
- Text output ->
"""

```
Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  t3 -> UrProjectDir\bin\Release\net5.0\win10-x64\UrProjectDir.dll
  t3 -> UrProjectDir\Dep\
```

"""
[UrProjectDir folder]
- [Look for the new folders]
- New sub-folders: bin, Dep
- Note: The compiled program is in the Dep subfolder named UrProjectDir.exe
- - The UrProjectDir.pdb file is used for debugging purposes and would not normally be deployed with your EXE file

[Windows CLI]
- [Remove the temporary folders in the UrProjectDir]
- `rd bin /s /q`
- `rd obj /s /q`
- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output shows as if you ran the command `dotnet run`

- Note: You can output the `System.AppContext.BaseDirectory` to find the Temp that holds the uncompressed program
"""

"""
[Program.vb file]
- [Replaces lines in Main sub]
- `Console.WriteLine(System.AppContext.BaseDirectory)`

[Windows CLI]
- [Compile into an EXE]
- `dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep`
- Note: If running DotNet Core 3.1,
- - `dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true -p:PublishSingleFile=true`
- -  The "--self-contained" option is incompatible with the "-p:PublishReadyToRun=true" and "-p:PublishSingleFile=true" options

- Note: When you choose the Portable publish option, you'll get a package that is capable of running on either x86 (32-bit) machines and x64 (64-bit) machines
- - The next run would have to JIT compile the application again as it is used
- - The advantage here is that you'd only need to distribute one package, and it'll run on both x86/x64 machines
- - `dotnet publish -c Release -r portable --self-contained`

- [Remove the temporary folders in the UrProjectDir]
- `rd bin /s /q`
- `rd obj /s /q`
- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output =
"""

```
C:\Users\UrUsername\AppData\Local\Temp\.net\UrProjectDir\SomeRandom-8-letters.SomeRandom-3-letters\
```

"""
- Note: This folder gets created on the first run the of UrProjectDir.exe
- - The second run starts faster because the files have already been extracted to this temporary folder
- - You can delete the temporary folder, and running the UrProjectDir.exe will create it again.

- Note: You can specify a different temporary folder by setting the Environment Variable `DOTNET_BUNDLE_EXTRACT_BASE_DIR`

- `SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%USERPROFILE%\Downloads\UrProjectDir\tmp`
- Note: You can set the Environment Variable in a batch file and it will not be saved for new Windows CLI windows.
- - To set it permanently, use `Control Panel` \ `System and Security` \ `System` \ `Advanced systems settings` \ `Advanced` tab \ `Environment Variables` button \ top or bottom section \ `New` button, Variable Name = `DOTNET_BUNDLE_EXTRACT_BASE_DIR`, Variable Value = `UrFullPathToTempDirectory`, `OK button`
- - Trying to use a relative directory path ends up not running the executable

- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output = 
"""

```
C:\Users\UrUsername\Downloads\UrProjectFolder\tmp\UrProjectFolder\SomeRandom-8-letters.SomeRandom-3-letters\
```

"""
- [Review the size of the TMP folder]
- `dir tmp /s`
- Text output = 23 Files, 8 Dirs

- [Remove the temporary directory]
- `rd tmp /s /q`

[UrProjectDir\Dep folder]
- [Create a script to run the project and clean up the temporary files]
- New file = UrProjectDir.cmd

[UrProjectDir.cmd file]
"""

```
@@ECHO OFF
SET CUR_DIR=%~dp0
SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%CUR_DIR%tmp
"%CUR_DIR%UrProjectDir.exe"
rd "%CUR_DIR%bin" /s /q 2> nul
rd "%CUR_DIR%obj" /s /q 2> nul
rd "%CUR_DIR%tmp" /s /q 2> nul
```

"""
[Windows CLI]
- [Run the clean-execution script]
- `Dep\UrProjectDir.cmd`
- Note: There is no tmp subfolder

VBNetCode\DotNet Core Installation using Binaries

VBCode WindowsOS
"""
[https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net50]
"""

<<<
As an alternative to the Windows installers for .NET, you can download and manually install the SDK or runtime. Manual install is usually performed as part of continuous integration testing. For a developer or user, it's generally better to use an installer.

Both .NET SDK and .NET Runtime can be manually installed after they've been downloaded. If you install .NET SDK, you don't need to install the corresponding runtime. First, download a binary release for either the SDK or the runtime from one of the following sites:

https://dotnet.microsoft.com/download/dotnet/5.0

https://dotnet.microsoft.com/download/dotnet-core

Create a directory to extract .NET to, for example %USERPROFILE%\dotnet. Then, extract the downloaded zip file into that directory.

By default, .NET CLI commands and apps won't use .NET installed in this way and you must explicitly choose to use it. To do so, change the environment variables with which an application is started:

```
set DOTNET_ROOT=%USERPROFILE%\dotnet
set PATH=%USERPROFILE%\dotnet;%PATH%
set DOTNET_MULTILEVEL_LOOKUP=0
```

This approach lets you install multiple versions into separate locations, then explicitly choose which install location an application should use by running the application with environment variables pointing at that location.

When DOTNET_MULTILEVEL_LOOKUP is set to 0, .NET ignores any globally installed .NET version. Remove that environment setting to let .NET consider the default global install location when selecting the best framework for running the application. The default is typically C:\Program Files\dotnet, which is where the installers install .NET.
<<<

"""
[https://docs.microsoft.com/en-us/dotnet/core/install/how-to-detect-installed-versions?pivots=os-windows]
"""

<<<
When you install .NET from an installer or script, it's installed to a standard folder. Much of the time the installer or script you're using to install .NET gives you an option to install to a different folder. If you choose to install to a different folder, adjust the start of the folder path.

dotnet executable in C:\program files\dotnet\dotnet.exe

.NET SDK in C:\program files\dotnet\sdk\{version}\

.NET Runtime in C:\program files\dotnet\shared\{runtime-type}\{version}\
<<<

VBNetCode\DotNet Core Installed Path

FileSystem Extract VBCode
"""
[Windows CLI]
- [Run the system information report]
- `dotnet --info`
"""

```
.NET Core SDK (reflecting any global.json):
 Version:   3.1.401
 Commit:    5b6f5e5005

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18363
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.401\

Host (useful for support):
  Version: 3.1.7
  Commit:  fcfdef8d6b

.NET Core SDKs installed:
  3.1.301 [C:\Program Files\dotnet\sdk]
  3.1.401 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
```

VBNetCode\DotNet Core New Project

Extract VBCode
[https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new]

<<<
You can run dotnet new --list or dotnet new -l to see a list of all installed templates. If the TEMPLATE value isn't an exact match on text in the Templates or Short Name column from the returned table, a substring match is performed on those two columns.

Starting with .NET Core 3.0 SDK, the CLI searches for templates in NuGet.org when you invoke the dotnet new command in the following conditions:

* If the CLI can't find a template match when invoking dotnet new, not even partial.
* If there's a newer version of the template available. In this case, the project or artifact is created but the CLI warns you about an updated version of the template.
<<<

[https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli]

"""
User-replaced value = UrProjectDir

[Windows CLI]
- [Navigate to the User Downloads folder]
- `cd %USERPROFILE%\Downloads`
- [Create a new DotNet Core project named UrProjectDir]
- `dotnet new console -lang VB -o UrProjectDir`
- Text output =
"""

```
Getting ready...
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj...
  Determining projects to restore...
  Restored C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj (in 65 ms).
Restore succeeded.
```

"""
- [Navigate to the new UrProjectDir]
- `cd UrProjectDir`

[UrProjectDir folder]
- [Look for the new files and folders]
- New files: UrProjectDir.vbproj and Program.vb
- New sub-folder: obj

[Windows CLI]
- [Download a dependency]
- `dotnet add package Figgle`
- Text output =
"""

```
  Determining projects to restore...
  Writing C:\Users\Dad\AppData\Local\Temp\tmpE018.tmp
info : Adding PackageReference for package 'Figgle' into project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info :   GET https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json
info :   OK https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json 104ms
info : Restoring packages for C:\Users\Dad\Downloads\t3\t3.vbproj...

info : Installing runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple 4.3.0.
info : Installing runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl 4.3.0.

info : Package 'Figgle' is compatible with all the specified frameworks in project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : PackageReference for package 'Figgle' version '0.4.0' added to file 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : Committing restore...
info : Writing assets file to disk. Path: C:\Users\Dad\Downloads\t3\obj\project.assets.json
log  : Restored C:\Users\Dad\Downloads\t3\t3.vbproj (in 8.04 sec).
```

"""
[Program.vb file]
- [Replace lines in Main sub]
- `Console.WriteLine(Figgle.FiggleFonts.Standard.Render("Hello, World!"))`

[Windows CLI]
- [Compile into an EXE and run it]
- `dotnet run`
- If you did not enter the program line incorrectly, Text output =
"""

```
Program.vb(5,79): error BC30037: Character is not valid.

The build failed. Fix the build errors and run again.
```

"""
- If you entered the program line correctly, Text output shows Hello World in a large font
"""

VBNetCode\DotNetCore Installation using Installer

VBCode WindowsOS
"""
[https://dotnet.microsoft.com/platform/support/policy/dotnet-core]
- 2020m11d24: .NET 5 is the current version of DotNet Core. It was released on November 10, 2020.

[https://dotnet.microsoft.com/download/dotnet-core]
- [Supported versions, record Version = .NET 5.0]
- Click link .NET 5.0 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/5.0]
- [record Release Information = v5.0.0, Build Apps column]
- [SDK grid, record OS = Windows]
- Click link x86 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-windows-x64-installer]
- Auto-download started -> Saves file

[Local Computer Downloads folder]
- [filename = dotnet-sdk-5.0.100-win-x64.exe]
- Run program -> Opens form

[Microsoft .NET SDK 5.0.100 (x64) Installer window]
- Click button Install -> Windows dialog
- Question: Do you want to allow the program to make changes to your computer?
- Click button Yes -> Closes dialog
- Wait for progress bar to complete -> Navigates page
- Note: Installation was successful
- Click button Close -> Closes window

[[VBNetCode\DotNet Core Installed Path]]

VBNetCode\File Exists

FileSystem Extract VBCode
```
Dim bolFILE_EXISTS = System.IO.File.Exists(flnDATA)

VBNetCode\File Size

FileSystem Extract VBCode
```
Dim sioFILE = New System.IO.FileInfo(flnDATA)
Dim intFILE_SIZE = sioFILE.Length

VBNetCode\Global functions passed as Classes

CodeLibrary AssignVariable VBCode
```
    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

VBNetCode\In-Memory Compile

CodeLibrary Extract VBCode
```
Namespace Mx
    Public Class ScriptRun
        ' Build a Hello World program graph using 
        ' System.CodeDom types.
        Public Class enmC_V_J
            Inherits bitBASE
            Public Shared CSharp As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared VisualBasic As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared JScript As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
        End Class 'enmC_V_J

        Public Shared Function RunCode(ur_provider As Mx.ScriptRun.enmC_V_J, ur_input_script As String, ur_assembly_folder As String) As String
            Dim strSOURCE_CODE = ur_input_script
            Dim stpERR_MSG = Strapd()
            Dim stpCODE_FILE = Strapd()
            ' Configure a CompilerParameters that links System.dll and produces the specified executable file.
            Dim objAPP_DOMAIN As AppDomain = Nothing
            Dim objCOMPILE_RUNNER As CompilerRunner = Nothing
            Dim objCOMPILER_PARM = New System.CodeDom.Compiler.CompilerParameters
            Dim objCOPMILER_RESULT As System.CodeDom.Compiler.CompilerResults = Nothing
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing

            If stpERR_MSG.Length = 0 Then
                'objAPP_DOMAIN = System.AppDomain.CreateDomain("MyDomain", AppDomain.CurrentDomain.Evidence, CreateSetup())
                'objCOMPILE_RUNNER = objAPP_DOMAIN.CreateInstanceFromAndUnwrap(GetType(CompilerRunner).Assembly.Location, GetType(CompilerRunner).FullName)
                objCOMPILE_RUNNER = New Mx.CompilerRunner
                stpERR_MSG.d(objCOMPILE_RUNNER.Compile(stpCODE_FILE.ToString, ur_provider.name, objCOMPILER_PARM))
            End If

            If stpERR_MSG.Length = 0 Then
                stpERR_MSG.d(objCOMPILE_RUNNER.Run("Mx.Class1", "RetVal"))
            End If

            If objAPP_DOMAIN IsNot Nothing Then
                'AppDomain.Unload(objAPP_DOMAIN)
            End If
            ' Return the results of compilation.
            Return stpERR_MSG.ToString
        End Function 'RunCode

        Public Shared Function CreateSetup() As AppDomainSetup
            Dim retSETUP = New AppDomainSetup
            With retSETUP
                .ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
                .ApplicationName = "TestDLL"
                .DisallowBindingRedirects = False
                .ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
                .LoaderOptimization = LoaderOptimization.MultiDomainHost
            End With
            CreateSetup = retSETUP
        End Function 'CreateSetup
    End Class 'ScriptRun

    Public Class CompilerRunner
        Inherits MarshalByRefObject

        Public cur_assembly As System.Reflection.Assembly = Nothing
        'AppDomain.CurrentDomain.FriendlyName = MyDomain

        Public Function Compile(ur_code As String, ur_provider As String, ur_compiler_parm As System.CodeDom.Compiler.CompilerParameters) As String
            Dim stpERR_MSG = Strapd()
            Me.cur_assembly = Nothing
            Dim provider As System.CodeDom.Compiler.CodeDomProvider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider(ur_provider) 'New Microsoft.VisualBasic.VBCodeProvider 
            Dim objCOMPILER_RESULT = provider.CompileAssemblyFromSource(ur_compiler_parm, ur_code) ' Strapd().d("Namespace Mx").dLine("Public Class Class1").dLine("Public Shared Function RetVal() As String").dLine("RetVal=""Hi""").dLine("End Function").dLine("End Class").dLine("End Namespace"))
            If objCOMPILER_RESULT.Errors.Count = 0 Then
                Me.cur_assembly = objCOMPILER_RESULT.CompiledAssembly

            Else
                stpERR_MSG.dLine("Compile Errors")
                stpERR_MSG.dLine()
                For Each errItem As System.CodeDom.Compiler.CompilerError In objCOMPILER_RESULT.Errors
                    stpERR_MSG.dLine(errItem.ErrorText & " [" & errItem.Line + 5 & "]")
                    stpERR_MSG.dLine()
                    stpERR_MSG.dLine()
                Next errItem

                stpERR_MSG.dLine(ur_code)
            End If 'objCOMPILER_RESULT

            Compile = stpERR_MSG.ToString
        End Function 'Comiple

        Public Function Run(ur_type_name As String, ur_method_name As String) As String
            Dim stpERR_MSG = Strapd()
            Dim t As System.Type = Me.cur_assembly.CreateInstance(ur_type_name).GetType()
            'Dim objRESULT = t.InvokeMember(ur_method_name, System.Reflection.BindingFlags.InvokeMethod, Nothing, Me.cur_assembly, {})
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing
            For Each m As System.Reflection.MethodInfo In t.GetMethods
                If m.Name = ur_method_name Then
                    objMETHOD_MAIN = m
                    Exit For
                End If
            Next m

            If objMETHOD_MAIN IsNot Nothing Then
                Dim objRESULT = objMETHOD_MAIN.Invoke(Nothing, Nothing)
                If objRESULT IsNot Nothing Then
                    stpERR_MSG.dLine(objRESULT.ToString)
                End If 'objRESULT
            End If 'objMETHOD_MAIN

            Run = stpERR_MSG.ToString
        End Function 'Run
    End Class 'CompileRunner
End Namespace 'Mx

VBNetCode\Send Keys

AssignVariable VBCode
Send one alt-tab

```
System.Windows.Forms.SendKeys.Send("%{TAB}")
```

Hold down Alt, press alt-tab twice, and release Alt

```
System.Windows.Forms.SendKeys.Send("%({TAB}{TAB})")
```

The Windows key is not so easy to emulate.
- Auto-It or Auto-Hotkey can do more complicated patterns
- VB.Net can use PInvoke to have more capabilities

VBNetCode\Text file to JSON Lines

TWCard Extract VBCode
This outputs a file that can be dragged into TiddlyWiki.

```
<$list variable=cur_char filter="[[UrPK]get[text]splitregexp[\n]join[]split[]each:value[]!match[ ]sort[]]">
<<cur_char>>:
<$list variable=disp_name filter="[[Unicode Char Names]getindex<cur_char>else[missing]]">
<<disp_name>>
</$list><!--disp_name-->
<br>
</$list><!--cur_char-->

[[Unicode Char Names]]
```


```
Dim strFILE_PATH = "UnicodeData.txt"
Dim strOUT_PATH = strFILE_PATH & ".json"
Using stmOUT_FILE = New System.IO.StreamWriter(strOUT_PATH)
	Dim qs = """"
	Dim strESC_DQT = "\" & qs
	stmOUT_FILE.Write("[{""created"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & ",""modified"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & "," &
		qs & "title" & qs & ":" & qs & "Unicode Char Names" & qs & ",""type"":""application/json"",""text"":""{")
	Using stmDATA = New System.IO.StreamReader(strFILE_PATH)
		Dim LINCTR = 0
		While stmDATA.EndOfStream = False
			Dim strLINE = stmDATA.ReadLine()
			Dim intFOUND_SPRTR = InStr(strLINE, ";")
			
			Dim strHEX = Mid(strLINE, 1, intFOUND_SPRTR - 1)
			Dim intCHAR = Cint("&H" & strHEX)
			Dim strCHAR = UCase(strHEX)
			Dim strPREFIX = Left(strCHAR, 2)
			If Len(strCHAR) <> 4 Then
				strPREFIX = ""
			End If
			
			If intCHAR < 32 Then
			  strCHAR = ""
			ElseIf intCHAR > 65534 OrElse
			  strPREFIX = "D8" OrElse
			  strPREFIX = "D9" OrElse
			  strPREFIX = "DA" OrElse
			  strPREFIX = "DB" OrElse
			  strPREFIX = "DC" OrElse
			  strPREFIX = "DD" OrElse
			  strPREFIX = "DE" OrElse
			  strPREFIX = "DF" Then
				strCHAR = "\u" & strHEX
			Else
				strCHAR = CHRW(intCHAR)
				If strCHAR = "\" Then
					strCHAR = "\\\\"
				ElseIf strCHAR = """" Then
					strCHAR = "\\\" & """"
				End If
			End If

			If strCHAR <> "" Then
				LINCTR += 1
				If LINCTR > 1 Then
					stmOUT_FILE.Write(",")
				End If
				stmOUT_FILE.Write("\n    " & strESC_DQT & strCHAR & strESC_DQT & ":" & " " & strESC_DQT & strLINE.Replace("\", "\\").Replace(Chr(10), "\n").Replace(qs, strESC_DQT).Replace("<", "&lt;") & strESC_DQT)
			End If
		End While 'stmDATA
	End Using 'stmDATA
	
	stmOUT_FILE.Write("\n}" & qs & "}]")
End Using 'stmOUT_FILE

VBNetCode\To Hex

Numbers Extract VBCode
"""
Change string with numbers (0 to 9) and/or letters (a-f) into decimal number

[q/a page]
- https://stackoverflow.com/questions/642417/how-do-you-convert-hex-to-decimal-using-vb-net

[sample code]
"""

```
Dim strTEXT = "FF"
Dim strHEX_CODE = "&H" & strTEXT
Dim intNUMBER = CInt(strHEX_CODE)
MsgBox(intNUMBER) -> 255

VBNetCode\Unicode Code Point

<<ext "Microsoft DotNet Char ConvertToUTF32">>

* Note: The index can be any character in the string

```
retval = char.ConvertToUtf32(s:="A", index:=0).Tostring
```

<<<
Result:

```
65
```
<<<

VBNetCode\UserBowl example

CodeLibrary Extract VBCode
```
    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As zapp_folder = TRow(Of enmUN).glbl.Trbase(Of zapp_folder).NewBitBase() : Public Class zapp_folder : Inherits enmUN : End Class
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared background_color As zbackground_color = TRow(Of enmUN).glbl.Trbase(Of zbackground_color).NewBitBase() : Public Class zbackground_color : Inherits enmUN : End Class
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_project_code As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared compiler_exe As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared form_title As zform_title = TRow(Of enmUN).glbl.Trbase(Of zform_title).NewBitBase() : Public Class zform_title : Inherits enmUN : End Class
        Public Shared path As zpath = TRow(Of enmUN).glbl.Trbase(Of zpath).NewBitBase() : Public Class zpath : Inherits enmUN : End Class
        Public Shared script_path As zscript_path = TRow(Of enmUN).glbl.Trbase(Of zscript_path).NewBitBase() : Public Class zscript_path : Inherits enmUN : End Class
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared window_status As zwindow_status = TRow(Of enmUN).glbl.Trbase(Of zwindow_status).NewBitBase() : Public Class zwindow_status : Inherits enmUN : End Class
    End Class

    Public Class enmUR_Color
        Inherits bitBASE
        Public Shared Clear As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Green As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Red As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
    End Class

    Public Class enmUR_Status
        Inherits bitBASE
        Public Shared Show As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
        Public Shared Close As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'db.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit(Have.WindowsMsgBox, Have.WindowsCboard)
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)
            Private enrBackground_Color As System.Drawing.Color
            Private enrUR_Color As enmUR_Color

            Public ReadOnly Property Background_Color_of_Form As System.Drawing.Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color_of_Form = Me.enrBackground_Color
                End Get
            End Property 'Background_Color_of_Form

            Public Property Background_Color As enmUR_Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color = Me.enrUR_Color
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As enmUR_Color)
                    Dim intCOLOR = System.Drawing.Color.Transparent
                    If value Is enmUR_Color.Red Then
                        intCOLOR = System.Drawing.Color.Red

                    ElseIf value Is enmUR_Color.Green Then
                        intCOLOR = System.Drawing.Color.Green
                    End If

                    Me.enrBackground_Color = intCOLOR
                    Me.enrUR_Color = value
                    Me.v(enmUB.contents) = value.name
                End Set
            End Property 'Contents

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_bowlname_is(ur_cmp As enmUN) As Boolean
                v_bowlname_is = AreEqual(Me.v(enmUB.bowl_name), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_cmp As enmUR_Color) As Boolean
                v_is = AreEqual(Me.Contents, ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit(ur_windowsmsgbox_env As Have.glblWindowsMsgBox, ur_windowscboard_env As Have.glblWindowsCboard)
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = ur_windowsmsgbox_env.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        ur_windowscboard_env.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Dim strASSEMBLY_EXE = mt
                Try
                    strASSEMBLY_EXE = My.Application.Info.Title
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_FOLDER = FileNamed()
                Try
                    flnASSEMBLY_FOLDER.wAssemblyDir(My.Application.Info)
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_PATH = flnASSEMBLY_FOLDER.gCopy.d(strASSEMBLY_EXE)
                Me.SelKey(enmUN.app_name).Contents = flnASSEMBLY_PATH.FileGroup
                Me.SelKey(enmUN.app_path).Contents = flnASSEMBLY_PATH
                Me.SelKey(enmUN.app_folder).Contents = flnASSEMBLY_FOLDER

                'enmUN.compiler_exe, enmUN.path take the first non-prefixed parameters; they are just file paths but without /parameter_name=
                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText, enmUN.compiler_exe, enmUN.path)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function 'InsFrom_Application

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCboard(ur_hdr As Boolean) As Integer
                ToCboard = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN

VBNetCode\Version

<<ext "WestWindCom Net Core Runtime">>
<<ext "SO.com RunTime Net 4.5">>

```
Function version_info() As String
version_info = "flag CLR 4.5 Features = " & If(Type.GetType(typeName:="System.Reflection.ReflectionContext", throwOnError:=False) Is Nothing, "", "True") & vbCrLf
version_info &= "flag CLR 4.51 Features = " & If(Type.GetType(typeName:="System.Runtime.GCLargeObjectHeapCompactionMode", throwOnError:=False) Is Nothing, "", "True") & vbCrLf
version_info &= "CLR Version = " & System.Environment.Version.ToString & vbCrLf
version_info &= "CLR Local Path = " & System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() & vbCrLf
version_info &= "Operating System = " & CType(System.Attribute.GetCustomAttribute(System.Reflection.Assembly.GetEntryAssembly(), GetType(System.Runtime.Versioning.TargetFrameworkAttribute)), System.Runtime.Versioning.TargetFrameworkAttribute).FrameworkName & " on " & System.Runtime.InteropServices.RuntimeInformation.OSDescription
End Function
```

VBNetProject

DOC
<<glbl_article_list>>

VBNetProject\~Clear Local

WindowsCLI CodeLibrary VBCode
```
rd /s /q bin
rd /s /q obj
pause

VBNetProject\~Rebiuld Local

CodeLibrary Extract VBCode
```
for %%f in (*.sln) do (
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
	
    for /D %%m in ("C:\Program Files (x86)\MSBuild\*\Bin\MSBuild.exe") do (
        "%%~m" /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
   )
:compile_complete
pause
del ..\Dep\*.exe
move bin\Release\*.exe ..\Dep
rd /s /q bin
rd /s /q obj
pause

VBNetProject\dbUserInputMock

CodeLibrary VBCode
!! Automatically convert the form to the dbUserInput class

```
Partial Public Class frmInput_1
    <System.Diagnostics.DebuggerHidden()>
    Public Shared Widening Operator CType(b As frmInput_1) As Mx.dbUserInput
        Return New Mx.dbUserInput(b, b.txtNotice_Message)
    End Operator
End Class 'frmInput_1
```

!! Setup the mock classes
* Create flat classes that have the desired values

```
Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock
End Namespace 'Mx2
```

* In a copy of the Mx.dbUserInput class, rename every `System.Windows.Forms` reference to `Mx2.Mock`

```
Option Strict On
Namespace Mx
    Public Class componentTextBox
        Private objTEXT_BOX As System.Windows.Forms.TextBox

        Public Sub New(ur_textbox As System.Windows.Forms.TextBox)
            objTEXT_BOX = ur_textbox
        End Sub

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objTEXT_BOX IsNot Nothing Then
                    Text = objTEXT_BOX.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objTEXT_BOX IsNot Nothing Then
                    objTEXT_BOX.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'componentTextBox

    Public Class dbUserInput
        Private objINPUT_FORM As System.Windows.Forms.Form
        Public txtNotice_Message As componentTextBox

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_input_form As System.Windows.Forms.Form, ur_notice_message_textbox As System.Windows.Forms.TextBox)
            objINPUT_FORM = ur_input_form
            Me.txtNotice_Message = New componentTextBox(ur_notice_message_textbox)
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Close()
            If objINPUT_FORM IsNot Nothing Then
                objINPUT_FORM.Close()
            End If
        End Sub

        Public Property BackColor As System.Drawing.Color
            <System.Diagnostics.DebuggerHidden()>
            Get
                BackColor = Nothing
                If objINPUT_FORM IsNot Nothing Then
                    BackColor = objINPUT_FORM.BackColor
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As System.Drawing.Color)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.BackColor = value
                End If
            End Set
        End Property 'BackColor

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objINPUT_FORM IsNot Nothing Then
                    Text = objINPUT_FORM.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'dbUserInput
End Namespace 'Mx
```

!! Create sample data
* Load the mock dbUserInput with the testing state

```
Dim mockTextBox = New Mock.TextBox
Dim mockForm = New Mock.Form
Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
Call Mx.UserAction.Run_Script_errhnd(mockUserInput)
```

* Compare the mock dbUserInput field changes to the expected result state

```
Dim strFOUND_RESULT = mockTextBox.Text
If strFOUND_RESULT = strEXPECTED_RESULT Then
	intPASS_COUNT += 1

Else
	intFAIL_COUNT += 1
	stpMOCK_REPORT.dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`").dLine())
End If 'strFOUND_RESULT
```

VBNetProject\DeveloperSettings

CodeLibrary VBCode
<<ext "DeveloperSettings HTM"">>

<<ext "DeveloperSettings ZIP"">>

VBNetProject\MxBaseEc13

CodeLibrary VBCode
<<ext "MxBase Classes">>

```
Option Strict On
Namespace Mx '2020m01d03
    Public Module ConstVar
        Public Const mt = ""
        Public Const qs = """"
        Public Const qt = "'"
        Public Const s = " "

        <System.Diagnostics.DebuggerHidden()>
        Public Function AreEqual(ur_val As String, ur_cmp As String) As Boolean
            AreEqual = String.Equals(ur_val, ur_cmp, System.StringComparison.CurrentCultureIgnoreCase)
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b0(ur_val As Integer) As Integer
            b0 = ur_val - 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b1(ur_val As Integer) As Integer
            b1 = ur_val + 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function ContainingText(ur_large_text As String, ur_small_text As String) As Boolean
            ContainingText = InStr(ur_large_text, ur_small_text, CompareMethod.Text) > 0
        End Function 'ContainingText
        <System.Diagnostics.DebuggerHidden()>
        Public Function gUTF8_FileEncoding() As System.Text.UTF8Encoding
            gUTF8_FileEncoding = glbl.gUTF8_Encoding
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function EndingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            EndingWithText = AreEqual(Right(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'EndingWithText
        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText(ur_value As String) As Boolean
            HasText = Not String.IsNullOrWhiteSpace(ur_value)
        End Function 'HasText
        <System.Diagnostics.DebuggerHidden()>
        Public Function StartingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            StartingWithText = AreEqual(Left(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'StartingWithText

        <System.Diagnostics.DebuggerHidden()>
        Public Function CmdOutput(ur_exec_path As String, Optional ur_exec_param As String = mt) As String
            Dim objPCS As New System.Diagnostics.Process()
            With 1 : Dim prcINFO = objPCS.StartInfo
                prcINFO.FileName = ur_exec_path
                prcINFO.Arguments = ur_exec_param
                prcINFO.UseShellExecute = False
                prcINFO.RedirectStandardOutput = True
                prcINFO.CreateNoWindow = True
            End With 'prcINFO

            objPCS.Start()
            CmdOutput = objPCS.StandardOutput.ReadToEnd()
            objPCS.WaitForExit()
        End Function 'CmdOutput

        <System.Diagnostics.DebuggerHidden()>
        Public Function FileNamed() As MxText.FileName
            FileNamed = New MxText.FileName
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Strapd() As Strap
            Strapd = New Strap
        End Function

        Public Class glbl
            Private Shared objUTF8_ENCODING As System.Text.UTF8Encoding

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If objUTF8_ENCODING Is Nothing Then
                    objUTF8_ENCODING = New System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier:=False, throwOnInvalidBytes:=True)
                End If
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function gUTF8_Encoding() As System.Text.UTF8Encoding
                Call glbl.Init()
                gUTF8_Encoding = glbl.objUTF8_ENCODING
            End Function
        End Class 'glbl
    End Module 'ConstVar

    Public Class ErrListBase
        Dim pstpNOTICE_MSG As Strap

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            pstpNOTICE_MSG = Strapd()
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Function DoContinue() As Boolean
            DoContinue = (Me.Found = False)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            If pstpNOTICE_MSG.Length > 0 Then
                pstpNOTICE_MSG.dLine().dLine()
            End If

            pstpNOTICE_MSG.dLine(ur_exception.Message)
            pstpNOTICE_MSG.dLine(Strapd().d("Error in @r1.@r2").r1(ur_methodbase.DeclaringType.Name).r2(ur_methodbase.Name).dS("(status: @r1)").r1(ur_procedure_status))
        End Sub 'dError_Data

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Stack(ur_exception As System.Exception)
            Dim hr As Integer = System.Runtime.InteropServices.Marshal.GetHRForException(ur_exception)
            pstpNOTICE_MSG.dLine(ur_exception.GetType.ToString & "(0x" & hr.ToString("X8") & "): " & ur_exception.Message & System.Environment.NewLine & ur_exception.StackTrace & System.Environment.NewLine)
            Dim st = New System.Diagnostics.StackTrace(ur_exception, True)
            For Each objFRAME In st.GetFrames
                If objFRAME.GetFileLineNumber() > 0 Then
                    pstpNOTICE_MSG.dLine("Line:" & objFRAME.GetFileLineNumber() & " Filename: " & System.IO.Path.GetFileName(objFRAME.GetFileName) & System.Environment.NewLine)
                End If
            Next objFRAME
        End Sub 'dError_Stack

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function Found() As Boolean
            Found = (pstpNOTICE_MSG.Length > 0)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = pstpNOTICE_MSG
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Throw_Error_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            Call Me.dError_Data(ur_exception, ur_methodbase, ur_procedure_status)
            Throw New LocalException(mt)
        End Sub 'Throw_Error_Data


        Public Class LocalException
            Inherits System.Exception

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String)
                MyBase.New(message)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String, inner As System.Exception)
                MyBase.New(message, inner)
            End Sub
        End Class 'LocalException
    End Class 'ErrListBase

    Public Class iWrap(Of T)
        Public v As T

        Public Sub New(ur_t As T)
            Me.v = ur_t
        End Sub
    End Class 'iWrap

    Public Class ObaCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Obalist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list As Obalist(Of T) = Nothing)
            Call MyBase.New(prv.TotalItems(ur_list))
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObaCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property v() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObaCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function TotalItems(Optional ur_list As Obalist(Of T) = Nothing) As Integer
                TotalItems = 0
                If ur_list IsNot Nothing Then
                    TotalItems = ur_list.Count
                End If
            End Function 'TotalItems
        End Class 'prv
    End Class 'ObaCTR

    Public Class ObjCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Objlist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_list As Objlist(Of T))
            Call MyBase.New(ur_list.Count)
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObjCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property row() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                row = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObjCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function
    End Class 'ObjCTR

    Public Class Obalist(Of T)
        Private vobjLIST() As T

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list() As T = Nothing)
            Me.vobjLIST = ur_list
        End Sub

        Public ReadOnly Property Count() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Count = Me.vobjLIST.Length
            End Get
        End Property

        Public Property Item(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                Item = Me.vobjLIST(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.vobjLIST(ur_index) = ur_val
            End Set
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function kvp() As ObaCTR(Of T)
            kvp = New ObaCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Obalist

    Public Class Objlist(Of T)
        Inherits System.Collections.Generic.List(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As ObjCTR(Of T)
            kvp = New ObjCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Objlist

    Public Class SDPCTR(Of T As {New})
        Inherits RCTR

        Private vsdpLIST As SdPair(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdplist As SdPair(Of T))
            Call MyBase.New(ur_sdplist.Count)
            Me.vsdpLIST = ur_sdplist
        End Sub

        Public Shadows ReadOnly Property Current() As SDPCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDPCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property l() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = Me.vsdpLIST.l_enm(Me.Indexenm)
            End Get
        End Property

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdpLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDPCTR

    Public Class SdPair(Of T As {New})
        Inherits Sdata
        Private vobjT As System.Collections.Generic.Dictionary(Of String, T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            vobjT = New System.Collections.Generic.Dictionary(Of String, T)
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function d(ur_val As String, ur_link As T) As SdPair(Of T)
            d = Me
            Call Me.Add(ur_val)
            Call vobjT.Add(ur_val, ur_link)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDPCTR(Of T)
            kvp = New SDPCTR(Of T)(Me)
        End Function

        Public Property l(ur_key As String) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = vobjT.Item(ur_key)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(ur_key) = ur_val
            End Set
        End Property

        Public Property l_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_b1 = vobjT.Item(Me.v_b1(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_b1(ur_index)) = ur_val
            End Set
        End Property

        Public Property l_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_enm = vobjT.Item(Me.v_enm(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_enm(ur_index)) = ur_val
            End Set
        End Property
    End Class 'SdPair

    Public Class RCTR
        Private pintMAX_NUM As Integer
        Private pintCUR_NUM As Integer

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(ByVal b As RCTR) As Integer
            Return b.Indexb1
        End Operator 'CType

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_max_num As Integer)
            Me.pintMAX_NUM = ur_max_num
        End Sub

        Public Shadows ReadOnly Property Current() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me.pintCUR_NUM
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function GetEnumerator() As RCTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public ReadOnly Property Indexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexb1 = Me.pintCUR_NUM
            End Get
        End Property

        Public ReadOnly Property Indexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexenm = b0(Me.pintCUR_NUM)
            End Get
        End Property

        Public ReadOnly Property LastIndexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexb1 = Me.pintMAX_NUM
            End Get
        End Property

        Public ReadOnly Property LastIndexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexenm = b0(Me.pintMAX_NUM)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function MoveNext() As Boolean
            MoveNext = (Me.pintCUR_NUM < Me.pintMAX_NUM)
            Me.pintCUR_NUM += 1
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Reset() As RCTR
            Reset = Me
            Me.pintCUR_NUM = 0
        End Function
    End Class 'RCTR

    Public Class SDACTR
        Inherits RCTR

        Private psdaLIST As Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdata As Sdata)
            Call MyBase.New(ur_sdata.Count)
            Me.psdaLIST = ur_sdata
        End Sub

        Public Shadows ReadOnly Property Current() As SDACTR
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDACTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.psdaLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDACTR

    Public Class Sdata
        Inherits System.Collections.Generic.List(Of String)

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_val As String) As Sdata
            d = Me
            Call Me.Add(ur_val)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ParamArray ur_val() As String) As Sdata
            dList = Me
            If ur_val IsNot Nothing Then
                For Each strENTRY In ur_val
                    If strENTRY Is Nothing Then
                        strENTRY = mt
                    End If

                    Call Me.Add(strENTRY)
                Next strENTRY
            End If
        End Function 'dList

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As Sdata
            gCopy = New Sdata().dList(Me.ToArray)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDACTR
            kvp = New SDACTR(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Split(ur_text As String, ur_sprtr As Char) As Sdata
            Dim sdaCMP = New Sdata
            Split = sdaCMP
            For Each strTEXT In ur_text.Split(ur_sprtr)
                sdaCMP.Add(strTEXT)
            Next
        End Function 'Split

        Public Property v_b1(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property v_enm(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Sdata

    Public Class Strap
        Private pstbTEXT As System.Text.StringBuilder

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            Me.pstbTEXT = New System.Text.StringBuilder
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(b As Strap) As String
            Return b.ToString
        End Operator

        <System.Diagnostics.DebuggerHidden()>
        Public Function Clear() As Strap
            Clear = Me
            Call Me.pstbTEXT.Clear()
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_text As String) As Strap
            d = Me.dSprtr(mt, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSV_Quoted(ur_index_b1 As Integer, ur_text As String) As Strap
            dCSV_Quoted = Me
            If ur_index_b1 > 1 Then
                Me.d(",")
            End If

            Me.d(qs).d(ur_text.Replace(qs, qs & qs)).d(qs)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ur_sprtr As String, ParamArray ur_text() As String) As Strap
            dList = Me
            If ur_text IsNot Nothing Then
                For Each strENTRY In ur_text
                    Call Me.dSprtr(ur_sprtr, strENTRY)
                Next strENTRY
            End If
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSVList(ParamArray ur_text() As String) As Strap
            dCSVList = Me
            If ur_text IsNot Nothing Then
                For ENTCTR = 0 To UBound(ur_text)
                    Me.dCSV_Quoted(ENTCTR + 1, ur_text(ENTCTR))
                Next ENTCTR
            End If
        End Function 'dCSVList

        <System.Diagnostics.DebuggerHidden()>
        Public Function dLine(Optional ur_text As String = "") As Strap
            dLine = Me.dSprtr(vbCrLf, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dS(ur_text As String) As Strap
            dS = Me.dSprtr(s, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dSprtr(ur_sprtr As String, ur_text As String) As Strap
            dSprtr = Me
            Me.pstbTEXT.Append(ur_sprtr).Append(ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function gCopy(ur_text As String) As Strap
            gCopy = New Strap().d(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText() As Boolean
            HasText = (Me.Length > 0)
        End Function

        Public ReadOnly Property Length As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Length = Me.pstbTEXT.Length
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function r1(ur_text As String) As Strap
            r1 = Me
            Call Me.pstbTEXT.Replace("@r1", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function r2(ur_text As String) As Strap
            r2 = Me
            Call Me.pstbTEXT.Replace("@r2", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function rx(ur_index As Integer, ur_text As String) As Strap
            rx = Me
            Call Me.pstbTEXT.Replace("@r" & ur_index, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = Me.pstbTEXT.ToString
        End Function
    End Class 'Strap

    Public Class bitBASE
        Public name As String
        Public seq As Integer
    End Class

    Public Class TRow(Of T As {New, bitBASE})
        Inherits Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            For Each intVAL In Me.RefColNames
                Me.Add(mt)
            Next
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Index_TableSplit(ur_table As Objlist(Of TRow(Of T)), ur_key As T) As SdPair(Of Objlist(Of TRow(Of T)))
            Dim sdpRET = New SdPair(Of Objlist(Of TRow(Of T)))
            Index_TableSplit = sdpRET
            Dim tblCHUNK As Objlist(Of TRow(Of T)) = Nothing
            For Each rowCHUNK In ur_table
                Dim strINDEX = rowCHUNK.v(ur_key)
                Dim intFOUND = sdpRET.IndexOf(strINDEX)
                If intFOUND < 0 Then
                    tblCHUNK = New Objlist(Of TRow(Of T))
                    sdpRET.d(strINDEX, tblCHUNK)
                Else
                    tblCHUNK = sdpRET.l_enm(intFOUND)
                End If

                tblCHUNK.Add(rowCHUNK)
            Next rowCHUNK

            Call sdpRET.Sort()
        End Function 'Index_TableSplit


        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As TRow(Of T)
            Dim sdaRET = New TRow(Of T)
            gCopy = sdaRET
            For Each kvpENTRY In Me.kvp
                sdaRET.v_enm(kvpENTRY.Indexenm) = kvpENTRY.v
            Next kvpENTRY
        End Function

        Public Function Link_Table(ur_table As Objlist(Of TRow(Of T)), ParamArray ur_key_list() As T) As Objlist(Of TRow(Of T))
            Dim tblRET = New Objlist(Of TRow(Of T))
            Link_Table = tblRET
            For Each rowCHUNK In ur_table
                Dim bolFOUND = True
                For Each intKEY In ur_key_list
                    If AreEqual(rowCHUNK.v(intKEY), Me.v(intKEY)) = False Then
                        bolFOUND = False
                        Exit For
                    End If
                Next intKEY

                If bolFOUND Then
                    tblRET.Add(rowCHUNK)
                End If
            Next rowCHUNK
        End Function 'Link_Table

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function PersistRead(ur_persist_path As String) As Objlist(Of TRow(Of T))
            Dim ttbRET = New Objlist(Of TRow(Of T))
            PersistRead = ttbRET
            If Mx.glbl.gWindowsFS.HasFile(ur_persist_path) Then
                Dim bolFIRST_LINE = True
                Dim lstREF_COL = New Objlist(Of T)
                Using stmIN_FILE = Mx.glbl.gWindowsFS.ReadStream(ur_persist_path)
                    Dim strLINE = mt
                    While stmIN_FILE.EndOfStream = False
                        strLINE &= stmIN_FILE.ReadLine
                        Dim bolBALANCED_QUOTES = True
                        For CHRCTR = 0 To strLINE.Length - 1
                            If strLINE(CHRCTR) = """"c Then
                                bolBALANCED_QUOTES = Not bolBALANCED_QUOTES
                            End If
                        Next CHRCTR

                        If bolBALANCED_QUOTES = False Then
                            strLINE &= vbCrLf

                        Else
                            Dim new_row = New TRow(Of T)
                            If Left(strLINE, 1) = vbLf Then
                                strLINE = Mid(strLINE, 2)
                            End If

                            If bolFIRST_LINE = True Then
                                bolFIRST_LINE = False
                                Dim bolCOL_MATCH = False
                                Dim sdaFIRST_ROW = MxText.CSVSplit(strLINE, vbTab)
                                For Each strENTRY In MxText.CSVSplit(strLINE, vbTab)
                                    Dim enmFOUND_KEY As T = Nothing
                                    For Each enmKEY In new_row.RefColKeys
                                        If AreEqual(enmKEY.name, strENTRY) Then
                                            enmFOUND_KEY = enmKEY
                                            bolCOL_MATCH = True
                                            Exit For
                                        End If
                                    Next enmKEY

                                    lstREF_COL.Add(enmFOUND_KEY)
                                Next strENTRY

                                If bolCOL_MATCH = False Then
                                    Exit While
                                End If

                            ElseIf HasText(strLINE) Then
                                For Each kvpCOL In MxText.CSVSplit(strLINE, vbTab).kvp
                                    Dim enmKEY = lstREF_COL.Item(kvpCOL.Indexenm)
                                    If enmKEY IsNot Nothing Then
                                        new_row.v(enmKEY) = kvpCOL.v
                                    End If
                                Next kvpCOL

                                ttbRET.Add(new_row)
                            End If 'bolFIRST_LINE

                            strLINE = mt
                        End If 'bolBALANCED_QUOTES
                    End While
                End Using 'stmIN_FILE
            End If 'ur_persist_path
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Sub PersistWrite(ur_table As Objlist(Of TRow(Of T)), ur_persist_path As MxText.FileName)
            If Mx.glbl.gWindowsFS.HasDir(ur_persist_path.gParentDir) = False Then
                Mx.glbl.gWindowsFS.CreateDirectory(ur_persist_path.gParentDir)
            End If

            Using stmOUT_FILE = Mx.glbl.gWindowsFS.WriteStream(ur_persist_path)
                For Each kvpROW In ur_table.kvp
                    stmOUT_FILE.Write(kvpROW.row.ToString(kvpROW.Indexb1 = 1, True))
                Next
            End Using 'stmOUT_FILE
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeys() As Objlist(Of T)
            RefColKeys = TRow(Of T).glbl.RefKeys
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeySearch(ur_name As String) As Objlist(Of T)
            RefColKeySearch = TRow(Of T).glbl.RefKeySearch(ur_name)
        End Function 'RefColKeySearch

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColNames() As Sdata
            RefColNames = TRow(Of T).glbl.RefNames
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ToCbrd(ur_hdr As Boolean) As Integer
            ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean, Optional ur_quoted As Boolean = False) As Strap
            Dim stpRET = New Strap
            ToString = stpRET
            If ur_hdr Then : For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : stpRET.d(kvpCOL.v) : Next kvpCOL : stpRET.dLine() : End If
            For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : If ur_quoted Then : stpRET.d(qs).d(Me.v_enm(kvpCOL.Indexenm).Replace(qs, qs & qs)).d(qs) : Else : stpRET.d(Me.v_enm(kvpCOL.Indexenm)) : End If : Next kvpCOL : stpRET.dLine()
        End Function


        Public Property v(ur_cl As T) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.Item(ur_cl.seq)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = ""
                End If

                Me.Item(ur_cl.seq) = ur_val
            End Set
        End Property

        Public Class glbl
            Private Shared sdaTCOL_NAME As Sdata
            Private Shared sdjTCOL_KEY As Objlist(Of T)

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME Is Nothing Then
                    Dim objTEST = GetType(T).GetFields()(0).GetValue(Nothing)
                End If

                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME IsNot Nothing Then
                    sdjTCOL_KEY = New Objlist(Of T)
                    Dim tpeCMP = GetType(T)
                    For Each kvpCOL In sdaTCOL_NAME.kvp
                        For Each objPROP In tpeCMP.GetFields()
                            If tpeCMP.DeclaringType Is tpeCMP Then
                                Dim objBIT = DirectCast(objPROP.GetValue(Nothing), bitBASE)
                                If objBIT.seq = kvpCOL.Indexenm Then
                                    sdjTCOL_KEY.Add(DirectCast(objPROP.GetValue(Nothing), T))
                                    Exit For
                                End If
                            End If 'tpeCMP
                        Next objPROP
                    Next kvpCOL
                End If 'sdaTCOL_NAME
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Function NewProp() As T
                Dim objRET = New T
                NewProp = objRET

                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Function 'NewProp

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub NewProp(ur_prop As T)
                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function NewBitBase() As T
                NewBitBase = glbl.NewProp()
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub NewBitBase(ur_prop As T)
                Call glbl.NewProp(ur_prop)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeys() As Objlist(Of T)
                Call glbl.Init()
                RefKeys = glbl.sdjTCOL_KEY
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeySearch(ur_name As String) As Objlist(Of T)
                Call glbl.Init()
                Dim ttbRET = New Objlist(Of T)
                RefKeySearch = ttbRET
                Dim intFOUND_INDEX = TRow(Of T).glbl.RefNames.IndexOf(ur_name)
                If intFOUND_INDEX >= b0(1) Then
                    ttbRET.Add(TRow(Of T).glbl.RefKeys(intFOUND_INDEX))
                End If
            End Function 'RefKeySearch

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefNames() As Sdata
                Call glbl.Init()
                RefNames = glbl.sdaTCOL_NAME
            End Function

            Public Class Trbase(Of W As {New, T})
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function NewBitBase() As W
                    Dim objRET = New W
                    NewBitBase = objRET
                    Call TRow(Of T).glbl.NewBitBase(objRET)
                End Function
            End Class 'Trbase
        End Class 'glbl
    End Class 'Trow

    Partial Public Class MxText 'Parse
        Public Class enmCMD_RET
            Inherits bitBASE
            Public Shared eq As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared fslash As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs_end As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared txt As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared unk As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared ws As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
        End Class

        Public Class Cmdline_UB(Of T As {New, bitBASE}, W As {New, bitBASE})
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                CommandLine_UBParm = prv.CommandLine_UBParm(ur_ub_key, ur_ub_val, ur_source_text, ur_default_field_list)
            End Function

            Class sCMDLINE
                Inherits Mx.Objlist(Of TRow(Of enmCMD_RET))

                <System.Diagnostics.DebuggerHidden()>
                Public Overloads Function ToString(ur_hdr As Boolean) As String
                    Dim stpRET = Strapd() : For Each kvpREC In Me.kvp : stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr)) : Next kvpREC : ToString = stpRET
                End Function 'ToString
                <System.Diagnostics.DebuggerHidden()>
                Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                End Function
            End Class 'sCMDLINE

            Class sCMD_RET
                Public ttbUB_PARM As Objlist(Of TRow(Of W))
                Public ttbCMD_PARM As sCMDLINE
            End Class

            Partial Private Class prv
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                    Dim objRET = New sCMD_RET
                    CommandLine_UBParm = objRET
                    objRET.ttbUB_PARM = New Objlist(Of TRow(Of W))
                    objRET.ttbCMD_PARM = New sCMDLINE
                    Dim rowCMD_PARM = New TRow(Of enmCMD_RET)
                    objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                    Dim sdaDEFAULT_PARMNAME = New Sdata
                    Dim sdaDEST_PARMS = TRow(Of T).glbl.RefNames
                    For Each intUN In ur_default_field_list
                        sdaDEFAULT_PARMNAME.d(intUN.name)
                    Next

                    Dim stpCOMPILE = Strapd()
                    Dim intPREV_CHUNK = enmCMD_RET.ws
                    Dim intCHUNK_C = enmCMD_RET.ws
                    For CHRCTR = 0 To ur_source_text.Length - 1
                        Dim chrC = ur_source_text(CHRCTR)
                        intCHUNK_C = gChunkType(chrC)
                        Dim intSPAN = 1
                        For SPNCTR = CHRCTR + 1 To ur_source_text.Length - 1
                            Dim chrS = ur_source_text(SPNCTR)
                            Dim intSPAN_C = gChunkType(chrS)
                            If intSPAN_C IsNot intCHUNK_C OrElse
                              intSPAN_C Is enmCMD_RET.qs Then
                                'Combine all chunks except for escaped quotes
                                intSPAN = SPNCTR - CHRCTR
                                Exit For
                            End If

                            If SPNCTR = ur_source_text.Length - 1 Then
                                intSPAN = SPNCTR + 1 - CHRCTR
                                Exit For
                            End If
                        Next SPNCTR

                        Dim strCHUNK = ur_source_text.Substring(CHRCTR, intSPAN)
                        If intPREV_CHUNK Is enmCMD_RET.ws Then
                            'Have ws, skip compiled ws; wait for fslash or default parm
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'skip compiled fslash
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip ws between parameters

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'compile unquoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = enmCMD_RET.txt
                                stpCOMPILE.Clear.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.fslash Then
                            'Have ws-fslash, compile txt parm name; wait for eq
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'qs between parm name and eq is unk
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq Then
                                'skip compile qe
                                rowCMD_PARM.v(enmCMD_RET.fslash) = stpCOMPILE.ToString
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = enmCMD_RET.eq

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'compile txt into parm name
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.eq Then
                            'Have ws-fslash-eq, skip compile; wait for txt
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'flush parameter as "=true"; start new parameter
                                stpCOMPILE.Clear.d("true")
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted parameter value
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'keep ws in eq

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'skip eq between paramater name and value

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'store param name, compile unquoted parameter value
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.txt Then
                            'Have ws-fslash-eq-txt, compile parm val; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                'Keep fslash and qs in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'Keep eq in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs Then
                            'Have ws-fslash-eq-qs, compile parm val; wait for qs_end
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'Keep fslash in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'hold parameter; skip this qs and look for another escaped qs or flush the parameter
                                intPREV_CHUNK = enmCMD_RET.qs_end

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'Keep ws, eq and txt in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs_end Then
                            'Have ws-fslash-eq-qs-qsend, compile parm val without ending quote; wait for qs or ws
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'qs_end then fslash without ws between is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'keep escaped qs
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'qs_end then ws or txt is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.unk Then
                            'Have unk, skip compile; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip parameter; start new parameter
                                rowCMD_PARM.v(enmCMD_RET.txt) = stpCOMPILE.ToString
                                rowCMD_PARM = New TRow(Of enmCMD_RET)
                                objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If
                        End If

                        CHRCTR += intSPAN - 1

                        If CHRCTR = ur_source_text.Length - 1 Then
                            'On last entry
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse intCHUNK_C Is enmCMD_RET.eq Then
                                'flush default parameter value
                                stpCOMPILE.Clear.d("true")
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs OrElse intCHUNK_C Is enmCMD_RET.txt Then
                                'flush parameter
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip trailing ws
                            End If
                        End If
                    Next CHRCTR
                End Function 'CommandLine_Chunk

                Private Class Flush_Ret
                    Public rowCMD_PARM As TRow(Of enmCMD_RET)
                    Public intPREV_CHUNK As enmCMD_RET
                End Class

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function Flush_Parameter(ur_ub_key As W, ur_ub_val As W, ur_cmdparm_row As TRow(Of enmCMD_RET), ur_parm_val As Strap, ur_new_prevchunk As enmCMD_RET, ur_refname_list As Sdata, ur_objret_arl As sCMD_RET) As Flush_Ret
                    Dim objRET = New Flush_Ret
                    Flush_Parameter = objRET
                    objRET.rowCMD_PARM = New TRow(Of enmCMD_RET)
                    ur_objret_arl.ttbCMD_PARM.Add(objRET.rowCMD_PARM)
                    objRET.intPREV_CHUNK = ur_new_prevchunk
                    'flush parameter
                    ur_cmdparm_row.v(enmCMD_RET.txt) = ur_parm_val
                    Dim intFOUND = ur_refname_list.IndexOf(ur_cmdparm_row.v(enmCMD_RET.fslash).ToLower)
                    If intFOUND >= 0 Then
                        With 1 : Dim sdaROW = New TRow(Of W)
                            sdaROW.v(ur_ub_key) = ur_refname_list.v_enm(intFOUND)
                            sdaROW.v(ur_ub_val) = ur_cmdparm_row.v(enmCMD_RET.txt)
                            ur_objret_arl.ttbUB_PARM.Add(sdaROW)
                        End With

                        'Skip parameter if not found
                    End If

                    ur_parm_val.Clear()
                End Function

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function gChunkType(ur_char As Char) As enmCMD_RET
                    If ur_char = vbCr OrElse
                  ur_char = vbLf OrElse
                  ur_char = " "c OrElse
                  ur_char = vbTab Then
                        gChunkType = enmCMD_RET.ws

                    ElseIf ur_char = "="c OrElse
                  ur_char = ":"c Then
                        gChunkType = enmCMD_RET.eq

                    ElseIf ur_char = "/"c Then
                        gChunkType = enmCMD_RET.fslash

                    ElseIf ur_char = """"c Then
                        gChunkType = enmCMD_RET.qs

                    Else
                        gChunkType = enmCMD_RET.txt
                    End If
                End Function 'gChunkType
            End Class 'prv
        End Class
    End Class 'MxText-Parse

    Partial Public Class MxText
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function CSVSplit(ByVal ur_line As String, Optional ur_separator As String = ",") As Sdata
            Dim sdaCMP = New Sdata
            CSVSplit = sdaCMP
            Dim objARRAY = ur_line.ToCharArray
            Dim objSPRTR = Mid(ur_separator, 1, 1).ToCharArray()(0)
            Dim objESCAPE_QUOTE = """"c

            Const cstSTART = 0
            Const cstESC = 1
            Const cstQS = 2
            Dim intPARSE_STATE = cstSTART
            Dim intLEN = Len(ur_line) - 1
            Dim stpFIELD As New Strap
            For intIX = 0 To intLEN
                Dim objCHR = objARRAY(intIX)
                Select Case intPARSE_STATE
                    Case cstESC
                        stpFIELD.d(objCHR)
                        intPARSE_STATE = cstQS

                    Case cstQS
                        If objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstSTART
                            Dim intNEXT_IX = intIX + 1
                            If intNEXT_IX < intLEN Then
                                If objARRAY(intNEXT_IX) = objESCAPE_QUOTE Then
                                    intPARSE_STATE = cstESC
                                End If 'intNEXT_IX
                            End If 'intNEXT_IX

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR

                    Case cstSTART
                        If objCHR = objSPRTR Then
                            sdaCMP.d(stpFIELD.ToString)
                            Call stpFIELD.Clear()

                        ElseIf objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstQS

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR
                End Select 'intPARSE_STATE
            Next intIX

            sdaCMP.d(stpFIELD)
        End Function 'CSVSplit
    End Class 'MxText-Csv

    Public Class MxText
        Public Class FileName
            Public FilePath As String
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.FilePath = mt
            End Sub 'New
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(ur_path As String)
                Me.FilePath = ur_path
            End Sub 'New

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As FileName) As String
                Return b.FilePath
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As String) As FileName
                Return New FileName(b)
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shadows Function ToString() As String
                ToString = Me.FilePath
            End Function 'ToString

            <System.Diagnostics.DebuggerHidden()>
            Public Function dAppendEXT(ur_ext As String) As FileName
                dAppendEXT = Me
                If ur_ext.StartsWith(".") = False Then
                    ur_ext = "." & ur_ext
                End If

                Me.FilePath &= ur_ext
            End Function 'dAppendEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function d(ur_file_name As String) As FileName
                d = Me
                If HasText(Me.FilePath) Then
                    Me.FilePath = System.IO.Path.Combine(Me.FilePath, ur_file_name)

                Else 'Me
                    Me.FilePath = ur_file_name
                End If 'Me
            End Function 'd

            <System.Diagnostics.DebuggerHidden()>
            Public Function dNowTextYMDHMS(ur_file_name As String, Optional ur_separator As String = "_") As FileName
                dNowTextYMDHMS = Me
                Me.d(ur_file_name & ur_separator & Now().ToString("yyyy\mMM\dddthh\mmm\sss").Replace("P12", "N12").Replace("A12", "A00").ToLower)
            End Function 'dNowTextYMDHMS

            Public Property Ext() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Ext = System.IO.Path.GetExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wEXT(value)
                End Set
            End Property 'Ext

            Public ReadOnly Property ExtAll() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ExtAll = Strapd().dList(mt, Me.ExtList.ToArray)
                End Get
            End Property 'ExtAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function ExtList() As Sdata
                Dim sdaDESC = Sdata.Split(Me.FilePath, "."c)
                ExtList = sdaDESC
                sdaDESC.RemoveAt(0)
                For Each ROWCTR In sdaDESC.kvp
                    sdaDESC.v_b1(ROWCTR) = "." & sdaDESC.v_b1(ROWCTR)
                Next ROWCTR
            End Function 'ExtList

            Public Property FileGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileGroup = System.IO.Path.GetFileNameWithoutExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.Ext
                End Set
            End Property 'FileGroup

            Public Property FileBaseGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileBaseGroup = mt
                    For Each strENTRY In Sdata.Split(Me.Name, "."c)
                        FileBaseGroup = strENTRY
                        Exit For
                    Next
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.ExtAll
                End Set
            End Property 'FileBaseGroup

            <System.Diagnostics.DebuggerHidden()>
            Public Function gCopy() As FileName
                gCopy = New FileName(Me)
            End Function 'gCopy

            <System.Diagnostics.DebuggerHidden()>
            Public Function gFullPath() As FileName
                gFullPath = New FileName(glbl.gWindowsFS.GetFullPath(Me.FilePath))
            End Function 'gFullPath

            <System.Diagnostics.DebuggerHidden()>
            Public Function gParentDir() As FileName
                gParentDir = New FileName(Me.ParentDir)
            End Function 'gParentDir

            Public Property Name() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Name = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If

                    If HasText(strPATH) Then
                        Name = System.IO.Path.GetFileName(strPATH)
                    End If
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wParentDir.d(value)
                End Set
            End Property 'Name

            Public Property ParentDir() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ParentDir = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If 'strPATH

                    If HasText(strPATH) Then
                        ParentDir = System.IO.Path.GetDirectoryName(strPATH)
                    End If 'strPATH
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Dim strFILE_NAME = Me.Name
                    If HasText(value) Then
                        Me.FilePath = System.IO.Path.Combine(value, strFILE_NAME)

                    Else 'value
                        Me.FilePath = strFILE_NAME
                    End If 'value
                End Set
            End Property 'ParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function ParentList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH = Me.PathList
                ParentList = sdaPATH
                sdaPATH.RemoveAt(b0(sdaPATH.Count))
            End Function 'ParentList

            <System.Diagnostics.DebuggerHidden()>
            Public Function PathList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH As New System.Collections.Generic.List(Of FileName)
                PathList = sdaPATH

                Dim sdaDESC = New Objlist(Of FileName)
                sdaDESC.Add(Me.gCopy)
                Dim objREDUCE = Me.gCopy
                Call objREDUCE.wParentDir()
                While HasText(objREDUCE.FilePath)
                    sdaDESC.Add(objREDUCE.gCopy)
                    Call objREDUCE.wParentDir()
                End While 'objREDUCE

                For Each objFILE In sdaDESC
                    sdaPATH.Add(objFILE)
                Next objFILE
            End Function 'PathList

            <System.Diagnostics.DebuggerHidden()>
            Public Function wAssemblyDir(ur_assembly_info As Microsoft.VisualBasic.ApplicationServices.AssemblyInfo) As FileName
                wAssemblyDir = Me
                Me.FilePath = ur_assembly_info.DirectoryPath.Replace("\bin\Debug", mt)
            End Function 'wAssemblyDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wClear() As FileName
                wClear = Me
                Me.FilePath = mt
            End Function 'wClear

            <System.Diagnostics.DebuggerHidden()>
            Public Function wEXT(ur_ext As String) As FileName
                wEXT = Me
                Dim strFILE_NAME = Me.FileGroup
                If Left(ur_ext, 1) <> "." Then
                    ur_ext = "." & ur_ext
                End If 'ur_ext

                Me.wParentDir.d(strFILE_NAME & ur_ext)
            End Function 'wEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function wParentDir() As FileName
                wParentDir = Me
                Me.FilePath = Me.ParentDir
            End Function 'wParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wTempFileName(ur_fs_proxy As Microsoft.VisualBasic.MyServices.FileSystemProxy) As FileName
                wTempFileName = Me
                Me.FilePath = ur_fs_proxy.GetTempFileName
                Call ur_fs_proxy.DeleteFile(Me.FilePath)
            End Function 'wTempFileName
        End Class 'FileName
    End Class 'MxText-FileName

    Partial Public Class glbl
        Public Class gCboard
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Clear()
                Call My.Computer.Clipboard.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetText() As String
                GetText = My.Computer.Clipboard.GetText
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function SetText(ur_text As String) As Integer
                If HasText(ur_text) Then
                    Call My.Computer.Clipboard.SetText(ur_text)
                    SetText = 1 + ur_text.Length - ur_text.Replace(vbLf, mt).Length
                Else
                    Call My.Computer.Clipboard.Clear()
                    SetText = 0
                End If
            End Function 'SetText
        End Class 'gCboard

        Public Class gDiagnostics
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function IsRunningWindow(ur_title As String) As Boolean
                IsRunningWindow = False
                For Each objCUR_PROC In System.Diagnostics.Process.GetProcesses()
                    If objCUR_PROC.MainWindowHandle.ToInt32 <> 0 AndAlso
                      AreEqual(objCUR_PROC.MainWindowTitle, ur_title) Then
                        IsRunningWindow = True
                        Exit For
                    End If
                Next objCUR_PROC
            End Function 'IsRunningWindow

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Read_CommandLineText(ur_exec_path As String, ur_exec_param As String) As String
                Dim prcCOMMAND_LINE = gDiagnostics.Start_CommandLine_Program(ur_exec_path, ur_exec_param)
                Read_CommandLineText = prcCOMMAND_LINE.StandardOutput.ReadToEnd()
                prcCOMMAND_LINE.WaitForExit()
            End Function 'Read_CommandLineText

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Start_CommandLine_Program(ur_exec_path As String, ur_exec_param As String) As System.Diagnostics.Process
                Dim retPROCESS As New System.Diagnostics.Process()
                Start_CommandLine_Program = retPROCESS
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.UseShellExecute = False
                    prcINFO.RedirectStandardOutput = True
                    prcINFO.RedirectStandardError = True
                    prcINFO.CreateNoWindow = True
                End With 'prcINFO

                retPROCESS.Start()
            End Function 'Start_Procses

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Start_Windows_Program(ur_exec_path As String, ur_exec_param As String)
                Dim retPROCESS As New System.Diagnostics.Process()
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.Verb = "Open"
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
                    prcINFO.UseShellExecute = True
                End With 'prcINFO

                retPROCESS.Start()
            End Sub 'Start_Procses
        End Class 'gDiagnostics

        Public Class gInteraction
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub AppActivate(ur_window_title As String)
                Microsoft.VisualBasic.Interaction.AppActivate(ur_window_title)
            End Sub
        End Class 'gInteraction

        Public Class gEnvironment
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine() As String
                CommandLine = System.Environment.CommandLine
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ExpandEnvironmentVariables(ur_path As String) As String
                ExpandEnvironmentVariables = System.Environment.ExpandEnvironmentVariables(ur_path)
            End Function
        End Class 'gEnvironment

        Public Class gMsgBox
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetResult(ur_message As String, ur_style As MsgBoxStyle, ur_title As String) As MsgBoxResult
                GetResult = MsgBox(ur_message, ur_style, ur_title)
            End Function
        End Class 'gMsgBox

        Public Class gThread
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Sleep(ur_milliseconds As Integer)
                System.Threading.Thread.Sleep(ur_milliseconds)
            End Sub
        End Class 'gThread

        Public Class gWindowsFS
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Copy(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Copy(ur_source_path, ur_dest_path, True)
            End Sub
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub CreateDirectory(ur_folder_path As String)
                System.IO.Directory.CreateDirectory(ur_folder_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Delete(ur_path As String)
                System.IO.File.Delete(ur_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = System.IO.Directory.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetDirectories(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetDirectories = System.IO.Directory.GetDirectories(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFullPath(ur_partial_path As String) As String
                GetFullPath = System.IO.Path.GetFullPath(ur_partial_path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasDir(ur_search_folder As String) As Boolean
                HasDir = System.IO.Directory.Exists(ur_search_folder)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasFile(ur_search_Path As String) As Boolean
                HasFile = System.IO.File.Exists(ur_search_Path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Move(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Move(ur_source_path, ur_dest_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadAllText(ur_file_path As String) As String
                ReadAllText = System.IO.File.ReadAllText(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadStream(ur_file_path As String) As System.IO.StreamReader
                ReadStream = New System.IO.StreamReader(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub WriteAllText(ur_file_path As String, ur_text As String)
                Call System.IO.File.WriteAllText(ur_file_path, ur_text, Mx.gUTF8_FileEncoding())
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function WriteStream(ur_file_path As String) As System.IO.StreamWriter
                WriteStream = New System.IO.StreamWriter(ur_file_path, False, Mx.gUTF8_FileEncoding())
            End Function
        End Class 'gWindowsFS
    End Class 'glbl

    Public Class TablePKEnum(Of E As {New, bitBASE}, P As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of P, T)
        Private PK As E

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_flag_populate_keys As Boolean = True)
            Me.ttb = New System.Collections.Generic.Dictionary(Of P, T)
            Me.PK = TRow(Of E).glbl.RefKeys.tr_b1(1)
            If ur_flag_populate_keys Then
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    Dim new_row = New T
                    new_row.v(Me.PK) = enmENTRY.name
                    Me.ttb.Add(enmENTRY, new_row)
                Next enmENTRY
            End If 'ur_empty_table
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ur_key As P) As Boolean
            ExistsKey = Me.ttb.ContainsKey(ur_key)
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim enmENTRY = prv.Get_PKStr(Me, ur_row)
            If enmENTRY Is Nothing Then
                Throw New System.Exception("Primary Key must exist in the enumeration: " & ur_row.v(Me.PK))

            ElseIf Me.ttb.ContainsKey(enmENTRY) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_row.v(Me.PK))

            Else
                Me.ttb.Add(enmENTRY, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            InsKey = ret
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKEnum(Of E, P, T)
            Dim ttbRET = New TablePKEnum(Of E, P, T)
            PersistRead = ttbRET
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Me.Ins(CType(row, T))
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T()
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ur_key As P) As T
            SelKey = Me.ttb.Item(ur_key)
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                ret = Me.ttb.Item(ur_key)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            UseKey = ret
        End Function 'UseKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        Private Class prv
            Public Shared Sub Assign_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T, ur_key As P)
                ur_row.v(ur_table.PK) = ur_key.name
            End Sub 'Assign_PKStr

            Public Shared Function Get_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T) As P
                Dim ret As P = Nothing
                Dim strPK = ur_row.v(ur_table.PK)
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    If AreEqual(enmENTRY.name, strPK) Then
                        ret = enmENTRY
                        Exit For
                    End If
                Next enmENTRY

                Get_PKStr = ret
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKEnum

    Public Class TablePKStr(Of E As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of String, T)
        Private PK As Objlist(Of E)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_pk_count As Integer)
            Me.ttb = New System.Collections.Generic.Dictionary(Of String, T)
            Me.PK = New Objlist(Of E)
            With 1 : Dim lstKEYS = TRow(Of E).glbl.RefKeys
                Dim intPK_COUNT = ur_pk_count
                If intPK_COUNT > lstKEYS.Count Then
                    intPK_COUNT = lstKEYS.Count
                End If

                For KEYCTR = 1 To ur_pk_count
                    Me.PK.Add(lstKEYS.Item(b0(KEYCTR)))
                Next
            End With 'lstKEYS
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ParamArray ur_key() As String) As Boolean
            ExistsKey = False
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("ExistsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                ExistsKey = Me.ttb.ContainsKey(strPK_KEY_COMBINED)
            End If 'ur_key
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function DelAll() As TablePKStr(Of E, T)
            DelAll = Me
            Call Me.ttb.Clear()
        End Function 'DelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_row)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

            Else
                Me.ttb.Add(strPK_KEY_COMBINED, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("InsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

                Else
                    ret = New T
                    Call prv.Assign_PKStr(Me, ret, ur_key)
                    Me.ttb.Add(strPK_KEY_COMBINED, ret)
                End If 'Me
            End If 'ur_key

            InsKey = ret
        End Function 'InsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKStr(Of E, T)
            PersistRead = Me
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Dim new_row = New T
                For Each enmENTRY In new_row.RefColKeys
                    new_row.v(enmENTRY) = row.v(enmENTRY)
                Next

                Me.Ins(new_row)
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("SelKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    ret = Me.ttb.Item(strPK_KEY_COMBINED)

                Else
                    ret = New T
                End If 'Me
            End If 'ur_key

            SelKey = ret
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelOnKey(ParamArray ur_key() As String) As TablePKStr(Of E, T)
            Dim ret = Me
            For KEYCTR = 1 To Me.PK.Count
                ret = ret.Sel(Me.PK.Item(b0(KEYCTR)), ur_key(b0(KEYCTR)))
            Next

            SelOnKey = ret
        End Function 'SelOnKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                ret = Me.ttb.Item(strPK_KEY_COMBINED)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(strPK_KEY_COMBINED, ret)
            End If

            UseKey = ret
        End Function 'UseKey

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Assign_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T, ur_key() As String)
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                For KEYCTR = 1 To intPK_KEYS
                    ur_row.v(ur_table.PK.Item(b0(KEYCTR))) = ur_key(b0(KEYCTR))
                Next
            End Sub 'Assign_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_key() As String) As String
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To intPK_KEYS
                    If KEYCTR = 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_key(b0(KEYCTR)).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T) As String
                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To ur_table.PK.Count
                    If KEYCTR > 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_row.v_b1(KEYCTR).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKStr


    Partial Public Class Have
        Partial Private Class prv_sample
            Private Class Have
                Private Shared tblUserBowl As sUserBowl

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Sub Connect()
                    If Have.tblUserBowl Is Nothing Then
                        Have.tblUserBowl = New sUserBowl
                    End If 'sdaTCOL_NAME
                End Sub 'Connect

                Public Class enmUB
                    Inherits bitBASE
                    Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                    Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                End Class

                Public Class enmUN
                    Inherits bitBASE
                    Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p1 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p2 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared to_clipboard As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                End Class

                'Public Shared Function UserBowl() As sUserBowl
                '    Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
                '    Call Have.Connect()
                '    UserBowl = Have.tblUserBowl
                '    If bolFIRST_INIT Then
                '        Call Have.tblUserBowl.InsFrom_Application()
                '        Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                '        Call Have.tblUserBowl.Cboard_CmdlineAudit()
                '    End If
                'End Function 'UserBowl

                Public Class rUserBowl
                    Inherits TRow(Of enmUB)

                    <System.Diagnostics.DebuggerHidden()>
                    Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                        vt = Me
                        Me.v(ur_enm) = ur_val
                    End Function

                    'Public Shadows Function Link_Table(ur_child_table As Have.sReport_Detl, ParamArray ur_key_list() As bitRP) As sReport_Detl
                    '    Dim tblRET = New sReport_Detl
                    '    Link_Table = tblRET
                    '    Dim sdpXLAT = New SdPair(Of bitRT)
                    '    Dim stpKEY_BINDINGS = Strapd()
                    '    For Each keyRP In ur_key_list
                    '        stpKEY_BINDINGS.dS(keyRP.name)
                    '        For Each keyRT In ur_child_table.SelFirst.RefColKeys
                    '            If AreEqual(keyRT.name, keyRP.name) Then
                    '                sdpXLAT.d(keyRP.name, keyRT)
                    '            End If
                    '        Next keyRT
                    '    Next keyRP

                    '    If sdpXLAT.Count <> ur_key_list.Length Then
                    '        Throw New System.Exception("Key bindings not found for RT/RP join: " & stpKEY_BINDINGS.ToString)

                    '    Else
                    '        For Each trwJOIN In ur_child_table.SelAll
                    '            Dim bolFOUND = True
                    '            For Each keyRP In ur_key_list
                    '                Dim keyRT = sdpXLAT.l(keyRP.name)
                    '                If AreEqual(trwJOIN.v(keyRT), Me.v(keyRP)) = False Then
                    '                    bolFOUND = False
                    '                    Exit For
                    '                End If
                    '            Next keyRP

                    '            If bolFOUND Then
                    '                tblRET.Ins(trwJOIN)
                    '            End If
                    '        Next trwJOIN
                    '    End If 'sdpXLAT
                    'End Function 'Link_Table
                End Class 'rUserBowl

                Public Class sUserBowl
                    Inherits TablePKEnum(Of enmUB, enmUN, rUserBowl)

                    'Public Sub Cboard_CmdlineAudit()
                    '    If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    '        Dim strAUDIT = Me.ToString(True)
                    '        Dim ins_msg = Mx.Have.MessageBox.Ins(
                    '            New Mx.Have.rMessageBox().
                    '                vt(enmMB.title, Me.SelKey(enmUN.app_name).v(enmUB.contents)).
                    '                vt(enmMB.text, strAUDIT),
                    '            MsgBoxStyle.OkCancel
                    '            )
                    '        If ins_msg.vUserResponse = MsgBoxResult.Ok Then
                    '            Mx.Have.Clipboard.Ins(
                    '                New Mx.Have.rClipboard().
                    '                vt(enmCB.text, strAUDIT)
                    '                )
                    '        End If
                    '    End If
                    'End Sub 'Cboard_CmdlineAudit

                    'Public Function InsFrom_Application() As rUserBowl
                    '    Dim ret = New rUserBowl
                    '    InsFrom_Application = ret
                    '    'Me.InsKey(enmUN.app_name, New MxText.FileName().d(Mx.Class1.SourcePath).FileGroup)
                    '    'Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                    '    'Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                    '    Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                    '    Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                    '    Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                    '    For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    '        Me.Ins(
                    '            New Have.rUserBowl().
                    '            vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                    '            vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                    '            )
                    '    Next
                    'End Function 'InsFrom_Application

                    'Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    '    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                    'End Function
                End Class 'sUserBowl
            End Class 'Have
        End Class 'prv_sample
    End Class 'Have.prv_sample
End Namespace 'Mx

VBNetProject\VBNetScript

VBCode WindowsOS
<<ext "VBNetScript.EXE">>

<<ext "VBNetScript.SLN">>

VBNS Project

DOC
<<glbl_article_list>>

VBNS Project\~MockTestReport

ErrorHandling Extract VBCode
```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
dbUserInputMock.vb
ScriptRun.vb
subs.vb
RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx2

Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock

    Public Class Want
        Public Shared Function CompileCode_Report_errhnd(ur_commandline_text As String) As Mx.Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Mx.Strapd()
            CompileCode_Report_errhnd = stpRET
            stpRET.d("RED").dLine()
            Dim objERR_LIST = New Mx.ErrListBase : Try
                Call Assistant.CompileCode_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'CompileCode_Report_errhnd
    End Class 'Want

    Public Class Assistant
        Public Shared Sub CompileCode_Report(ur_ret As Mx.Strap)
            Dim windowsfs_env = Have.WindowsFS
            Dim userbowl_cart = Have.UserBowl
            Dim appfolder_bowlname = enmUN.app_folder
            Dim mocktest_cart = Have.MockTest
            Dim intRECS_INSERTED = mocktest_cart.Apply(userbowl_cart, appfolder_bowlname, windowsfs_env)
            Dim intRECS_TESTED = mocktest_cart.Apply(windowsfs_env)

            Dim from_messagebox_bowlname = userbowl_cart.Apply(mocktest_cart, ur_ret)
        End Sub 'CompileCode_Report
    End Class 'Assistant

    Partial Public Class Have
        Partial Public Class sMockTest
            Public Function Apply(ur_userbowl_cart As Have.sUserBowl, ur_appfolder_bowlname As enmUN, ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_ADDED = 0
                Dim strSEARCH_TEST_NAME = "MockTest\*.mock_commandline.txt"
                Dim strSEARCH_RESULT_NAME = ".mock_expect.txt"
                Dim flnAPP_FOLDER = Mx.FileNamed.d(ur_userbowl_cart.SelKey(ur_appfolder_bowlname).Contents)
				Dim fltSEARCH_MOCK_COMMANDLINE = flnAPP_FOLDER.gCopy.d(strSEARCH_TEST_NAME)
                For Each strPATH In ur_windowsfs_env.GetFiles(fltSEARCH_MOCK_COMMANDLINE.gParentDir, fltSEARCH_MOCK_COMMANDLINE.Name, System.IO.SearchOption.TopDirectoryOnly)
					
                    Dim flnTEST_FILE_PATH = Mx.FileNamed.d(strPATH)
                    Dim rowMOCK_TEST = Me.InsKey(strPATH)
                    retREC_ADDED += 1
                    Dim flnTEST_CODE_PATH = flnTEST_FILE_PATH.gParentDir.d(Mx.FileNamed().d(flnTEST_FILE_PATH.FileGroup).FileGroup)
                    For Each strTEST_CODE_PATH In ur_windowsfs_env.GetFiles(flnTEST_CODE_PATH.gParentDir, flnTEST_CODE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.test_code_file, strTEST_CODE_PATH)
                        Exit For
                    Next
					
                    Dim flnRESULT_FILE_PATH = flnTEST_CODE_PATH.gCopy.dAppendEXT(strSEARCH_RESULT_NAME)
                    For Each strEXPECTED_RESULT_PATH In ur_windowsfs_env.GetFiles(flnRESULT_FILE_PATH.gParentDir, flnRESULT_FILE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.mock_expect_file, strEXPECTED_RESULT_PATH)
                        Exit For
                    Next
                Next strPATH

                Apply = retREC_ADDED
            End Function 'Apply ur_userbowl_cart

            Public Function Apply(ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_TESTED = 0
                For Each rowMOCK_TEST In Me.SelAll
                    retREC_TESTED += 1
                    If Mx.HasText(rowMOCK_TEST.v(enmMT.test_code_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Test Code File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    ElseIf Mx.HasText(rowMOCK_TEST.v(enmMT.mock_expect_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Mock Expect File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    Else
						Dim strTEST_CODEFILE_PATH = rowMOCK_TEST.v(enmMT.test_code_file)
                        Dim strCOMMANDLINE_PARMS = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_commandline_file))
                        Dim strEXPECTED_RESULT = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_expect_file))

                        Dim mockTextBox = New Mock.TextBox
                        Dim mockForm = New Mock.Form
                        Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
                        Dim stpTEST_COMMANDLINE = Mx.Strapd().d("vbnetscript.exe").dS("/path=").dSprtr(Mx.qs, strTEST_CODEFILE_PATH).d(Mx.qs).dS(strCOMMANDLINE_PARMS)
                        Call Mx.Want.Compile_And_Run_Script_errhnd(mockUserInput, stpTEST_COMMANDLINE)
                        Dim strFOUND_RESULT = mockTextBox.Text
                        If strFOUND_RESULT = strEXPECTED_RESULT Then
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "1")
						
                        Else
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
                            rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`"))
                        End If 'strFOUND_RESULT
                    End If
                Next rowMOCK_TEST

                Apply = retREC_TESTED
            End Function 'Apply ur_windowsfs_env
        End Class 'sMockTest

        Partial Public Class sUserBowl
            Public Function Apply(ur_mocktest_cart As Have.sMockTest, ur_ret As Mx.Strap) As enmUN
                Dim retUN = enmUN.from_messagebox
                Apply = retUN

                Dim intTEST_PASS = 0
                Dim intTEST_FAIL = 0
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "1" Then
                        intTEST_PASS += 1

                    Else
                        intTEST_FAIL += 1
                    End If
                Next rowMOCK_TEST

                If intTEST_PASS = ur_mocktest_cart.SelAll.Count Then
                    ur_ret.Clear().dLine("GREEN").dLine()
                End If

                ur_ret.dLine(intTEST_PASS.ToString).dS("Tests passed")
                ur_ret.dLine(intTEST_FAIL.ToString).dS("Tests failed")
				ur_ret.dLine()
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "0" Then
                        ur_ret.dLine(rowMOCK_TEST.v(enmMT.test_result_text))
						ur_ret.dLine()
                    End If
                Next rowMOCK_TEST
            End Function 'Apply ur_messagebox_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblMockTest As sMockTest
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblMockTest = New sMockTest
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmMT
        Inherits Mx.bitBASE
        Public Shared mock_commandline_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared mock_expect_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_code_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_result_text As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_pass_count As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
    End Class 'enmMT

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function MockTest() As sMockTest
            Call Have.Connect()
            MockTest = Have.tblMockTest
        End Function

        Public Class rMockTest
            Inherits Mx.TRow(Of enmMT)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmMT, ur_val As String) As rMockTest
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rMockTest

        Public Class sMockTest
            Inherits Mx.TablePKStr(Of enmMT, rMockTest)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                MyBase.New(1)
            End Sub
        End Class
    End Class 'enmMT

    Public Class enmUB
        Inherits Mx.bitBASE
        Public Shared bowl_name As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits Mx.bitBASE
        Public Shared app_folder As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits Mx.bitBASE
        Public Shared Ok As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits Mx.TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = Mx.AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If Mx.HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = Mx.MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = Mx.qs & Have.CmdLineText.Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                Me.SelKey(enmUN.cmdline_table).Contents = Mx.qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx2

VBNS Project\~VersionUpd

AssignVariable Filter VBCode
```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.FileUpdate_Report_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.FileUpdate_Report_errhnd
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub FileUpdate_Report(ur_ret As Strap)
            Dim userbowl_cart = Have.UserBowl
            Dim appname_bowlname = enmUN.app_name
            Dim appfolder_bowlname = enmUN.app_folder
            Dim windows_msgbox_env = Have.WindowsMsgBox
            Dim windows_fs_env = Have.WindowsFS
            Dim tempfile_cart = Have.TempFile
            tempfile_cart.Apply(userbowl_cart.SelKey(appfolder_bowlname), windows_fs_env)
            Dim report_output_bowlname = userbowl_cart.Apply(tempfile_cart)
            Dim from_messagebox_bowlname = userbowl_cart.Apply(
                ur_userbowl_text:=userbowl_cart.SelKey(report_output_bowlname),
                ur_userbowl_appname:=userbowl_cart.SelKey(appname_bowlname),
                ur_messagebox_env:=windows_msgbox_env
                )
        End Sub 'FileUpdate_Report

        Public Shared Function FileUpdate_Report_errhnd() As Strap
            Dim stpRET = Strapd()
            FileUpdate_Report_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call FileUpdate_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'FileUpdate_Report_errhnd
    End Class 'Want

    Partial Public Class Have
        Partial Class sTempFile
            Public Sub Apply(ur_app_folder As Have.rUserBowl, ur_windows_fs_env As Have.glblWindowsFS)
                Dim flnROOT_FOLDER = FileNamed().d(ur_app_folder.v(enmUB.contents))
                Dim flnMY_PROJECT = flnROOT_FOLDER.gCopy.d("My Project")
                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnROOT_FOLDER, "*.vbproj", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.VBProj, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.VBProj).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.VBProj.name).dS("file in folder"))
                End If

                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnMY_PROJECT, "AssemblyInfo.vb", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.AssemblyInfo, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.AssemblyInfo).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.AssemblyInfo.name).dS("file in folder"))
                End If
            End Sub 'Apply(ur_app_folder
        End Class 'sTempFile

        Partial Public Class sUserBowl
            Public Function Apply(ur_userbowl_text As Have.rUserBowl, ur_userbowl_appname As Have.rUserBowl, ur_messagebox_env As Have.glblWindowsMsgBox) As bitBASE
                Dim retUN = enmUN.from_messagebox
                Apply = retUN
                Dim enrUSER_INPUT = ur_messagebox_env.GetResult(
                    ur_message:=ur_userbowl_text.v(enmUB.contents),
                    ur_title:=ur_userbowl_appname.v(enmUB.contents),
                    ur_style:=MsgBoxStyle.OkOnly
                    )

                If enrUSER_INPUT = MsgBoxResult.Ok Then
                    Me.InsKey(retUN, enmUR.Ok)
                End If
            End Function 'Apply ur_messagebox_cart

            Public Function Apply(ur_tempfile_cart As Have.sTempFile) As enmUN
                Dim retUN = enmUN.report_output
                Apply = retUN
                Dim strDATE = Today.ToString("yyyy.MM.dd")
                Dim intCURRENT = 1

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.VBProj.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<ApplicationRevision>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationRevision>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, InStr(strPARSE, "<") - 1)
                                    If System.Int32.TryParse(strPARSE, intCURRENT) Then
                                        intCURRENT += 1
                                    End If

                                ElseIf StartingWithText(strLINE.TrimStart, "<ApplicationVersion>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationVersion>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, 10)
                                    If AreEqual(strPARSE, strDATE) = False Then
                                        intCURRENT = 1
                                    End If 'strPARSE

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationRevision>")
                                    stmSECOND.Write(intCURRENT)
                                    stmSECOND.WriteLine("</ApplicationRevision>")

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationVersion>")
                                    stmSECOND.Write(Strapd().d(strDATE).d(intCURRENT.ToString("00")).d(".%2a"))
                                    stmSECOND.WriteLine("</ApplicationVersion>")

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.AssemblyInfo.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyVersion(") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyVersion").d("(").d(qs).d(Today.ToString("yyyy.MM.dd")).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                ElseIf StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyFileVersion") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyFileVersion").d("(").d(qs).d(strDATE).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                Me.InsKey(retUN, Strapd().d("Files updated:").dS(ur_tempfile_cart.SelAll.Count.ToString))
            End Function 'Apply ur_tempfield_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblTempFile As sTempFile
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblTempFile = New sTempFile
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmTF
        Inherits bitBASE
        Public Shared file_search As enmTF = TRow(Of enmTF).glbl.NewBitBase()
        Public Shared filename As enmTF = TRow(Of enmTF).glbl.NewBitBase()
    End Class

    Public Class enmTN
        Inherits bitBASE
        Public Shared AssemblyInfo As enmTN = TRow(Of enmTN).glbl.NewBitBase()
        Public Shared VBProj As enmTN = TRow(Of enmTN).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function TempFile() As sTempFile
            Call Have.Connect()
            TempFile = Have.tblTempFile
        End Function

        Public Class rTempFile
            Inherits TRow(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmTF, ur_val As String) As rTempFile
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rTempFile

        Public Class sTempFile
            Private ttb As Objlist(Of rTempFile)
            Private PK As Objlist(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rTempFile)
                Me.PK = New Objlist(Of enmTF)
                Me.PK.Add(enmTF.file_search)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Del(ur_col As enmTF, ur_val As String)
                For ROWCTR = Me.ttb.Count To 1 Step -1
                    If AreEqual(Me.ttb.tr_b1(ROWCTR).v(ur_col), ur_val) Then
                        Me.ttb.RemoveAt(b0(ROWCTR))
                    End If
                Next ROWCTR
            End Sub 'Del

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Ins(ur_from As rTempFile)
                Dim ttbSEL = Me
                Dim stpPK_LIST = Strapd()
                For Each keyPK In Me.PK
                    Dim strCUR_KEY = ur_from.v(keyPK)
                    If stpPK_LIST.Length > 0 Then stpPK_LIST.d(", ")
                    stpPK_LIST.d(strCUR_KEY)
                    If HasText(strCUR_KEY) = False Then
                        Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("PK value must have data:").dS(keyPK.name))
                    Else
                        ttbSEL = ttbSEL.Sel(keyPK, ur_from.v(keyPK))
                    End If
                Next keyPK

                If ttbSEL.SelAll.Count > 0 Then
                    Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("must have unique PK values:").dS(stpPK_LIST.ToString))
                Else
                    Me.ttb.Add(ur_from)
                End If
            End Sub 'Ins

            <System.Diagnostics.DebuggerHidden()>
            Public Sub InsKey(ur_key As enmTN, ur_val As String)
                Dim ret = Me.SelKey(ur_key)
                If HasText(ret.v(enmTF.filename)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmTF.filename, ur_val)
                End If
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmTF, ur_value As String) As sTempFile
                Dim retUB = New sTempFile
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rTempFile)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmTN) As rTempFile
                Dim ret As rTempFile = Nothing
                Dim strKEY = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmTF.file_search), strKEY) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rTempFile
                    Me.ttb.Add(
                        ret.
                        vt(enmTF.file_search, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sTempFile
    End Class 'TF

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Private ttb As Objlist(Of rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rUserBowl)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rUserBowl) As rUserBowl
                Ins = ur_from
                Me.ttb.Add(ur_from)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As String) As rUserBowl
                Dim ret = Me.SelKey(ur_key)
                InsKey = ret
                If HasText(ret.v(enmUB.contents)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmUB.contents, ur_val)
                End If
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As enmUR) As rUserBowl
                InsKey = Me.InsKey(ur_key, ur_val.name)
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.InsKey(enmUN.app_name, FileNamed().d(Mx.Class1.SourcePath).FileGroup)
                Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmUB, ur_value As String) As sUserBowl
                Dim retUB = New sUserBowl
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rUserBowl)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmUN) As rUserBowl
                Dim ret As rUserBowl = Nothing
                Dim strUN = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmUB.bowl_name), strUN) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rUserBowl
                    Me.ttb.Add(
                        ret.
                        vt(enmUB.bowl_name, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

VBNS Project\Roman to Decimal

Numbers Extract VBCode
<<ext "Roman to Decimal ZIP">>

* Asks for a Roman Numeral
* Returns a decimal number or an error with the invalid sequence and the broken rule

```
Namespace Mx
	Public Class mb
		Public Shared FirstExec As Object
		Public Shared uinput As Microsoft.VisualBasic.MsgBoxResult

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub ask(ur_text As String)
			Call prv.Connect()
			If mb.uinput <> MsgBoxResult.Cancel Then
				mb.uinput = Microsoft.VisualBasic.MsgBox(ur_text, MsgBoxStyle.OkCancel, "")
			End If
		End Sub 'ask

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Function GetText(ur_question As String) As String
			GetText = Microsoft.VisualBasic.InputBox(ur_question, "")
		End Function

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub reset()
			Call prv.Connect()
			mb.uinput = MsgBoxResult.Ok
		End Sub

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Sub Connect()
				If mb.FirstExec Is Nothing Then
					mb.uinput = MsgBoxResult.Ok
					mb.FirstExec = "done"
				End If
			End Sub 'Connect
		End Class 'prv
	End Class 'mb

	Public Class UserAction
		Public Shared Function Roman_Numeral_Conversion_Report() As String
			mb.reset()
			Dim strRET_MSG = ""
			Dim strNUMERAL = mb.GetText("Enter a Roman numeral")
			Dim strDECIMAL = Assistant.Roman_Numeral_Conversion_Result(strNUMERAL)
			strRET_MSG = strNUMERAL & " rom. = " & strDECIMAL & " dec."
			Roman_Numeral_Conversion_Report = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Report
	End Class 'UserAction

	Public Class Assistant
		Public Shared Function Roman_Numeral_Conversion_Result(ur_numeral As String) As String
			Dim strRET_MSG = ""
			Dim rmnNUMERAL = New Mx.glblRomanNumeral(ur_numeral)
			strRET_MSG = rmnNUMERAL.Validation_Message
			If strRET_MSG = "" Then
				strRET_MSG = rmnNUMERAL.ToInteger.ToString
			End If

			Roman_Numeral_Conversion_Result = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Result
	End Class 'Assistant

	Public Class glblRomanNumeral
		Private strpNumeral As String

		Private Enum enmLH
			low_or_high_number
			high_number
			low_number
		End Enum

		Private siaSymbol_Size As Mx.sia

		<System.Diagnostics.DebuggerHidden()>
		Public Sub New(ur_numeral As String)
			Me.strpNumeral = ur_numeral.Trim.ToUpper
			Me.siaSymbol_Size = prv.glbl_Symbol_Sizes()
		End Sub

		Public ReadOnly Property Numeral As String
			<System.Diagnostics.DebuggerHidden()>
			Get
				Numeral = Me.strpNumeral
			End Get
		End Property 'Numeral

		Public Function IsValid() As Boolean
			IsValid = (Me.Validation_Message = "")
		End Function

		Public Function Validation_Message() As String
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_Valid

			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, "", symbol_size_table)

			Validation_Message = clrRET_STATE.strNOTICE_MSG
		End Function 'Validation_Message

		Public Function ToInteger() As Integer
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_State
			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				Dim clPREV_STATE = clrRET_STATE
				clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, "", symbol_size_table)

			ToInteger = clrRET_STATE.intRET_NUM
		End Function 'ToInteger

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function glbl_Symbol_Sizes() As Mx.sia
				Dim retSIA = New Mx.sia
				glbl_Symbol_Sizes = retSIA
				retSIA.Add("I", 1)
				retSIA.Add("V", 5)
				retSIA.Add("X", 10)
				retSIA.Add("L", 50)
				retSIA.Add("C", 100)
				retSIA.Add("D", 500)
				retSIA.Add("M", 1000)

				glbl_Symbol_Sizes = retSIA
			End Function 'glbl_Symbol_Sizes

			Public Class Loop_State
				Public enrSTATE As enmLH
				Public strLOW_OR_HIGH_TEMP As String
				Public intRET_NUM As Integer

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Me.enrSTATE = enmLH.high_number
					Me.strLOW_OR_HIGH_TEMP = ""
					Me.intRET_NUM = 0
				End Sub 'New
			End Class 'Loop_State

			Public Class Loop_Valid
				Public strVAL_FOUR As String
				Public strVAL_THREE As String
				Public strVAL_TWO As String
				Public strVAL_ONE As String
				Public intVAL_FOUR As Integer
				Public intVAL_THREE As Integer
				Public intVAL_TWO As Integer
				Public intVAL_ONE As Integer
				Public strNOTICE_MSG As String

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Call prvLoop_Valid.Reset_Symobls(Me)
					Me.strNOTICE_MSG = ""
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia)
					Me.strVAL_FOUR = ur_state.strVAL_THREE
					Me.intVAL_FOUR = ur_state.intVAL_THREE
					Me.strVAL_THREE = ur_state.strVAL_TWO
					Me.intVAL_THREE = ur_state.intVAL_TWO
					Me.strVAL_TWO = ur_state.strVAL_ONE
					Me.intVAL_TWO = ur_state.intVAL_ONE
					Me.strVAL_ONE = ur_new_symbol
					Me.intVAL_ONE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
					Me.strNOTICE_MSG = ur_state.strNOTICE_MSG
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub Assign_NoticeMsg(ur_message As String)
					If strNOTICE_MSG <> "" Then
						strNOTICE_MSG &= vbCrLf & vbCrLf
					End If

					strNOTICE_MSG &= ur_message
					Call prvLoop_Valid.Reset_Symobls(Me)
				End Sub 'Assign_NoticeMsg

				Private Class prvLoop_Valid
					Public Shared Sub Reset_Symobls(ur_state As prv.Loop_Valid)
						ur_state.strVAL_FOUR = ""
						ur_state.intVAL_FOUR = 0
						ur_state.strVAL_THREE = ""
						ur_state.intVAL_THREE = 0
						ur_state.strVAL_TWO = ""
						ur_state.intVAL_TWO = 0
						ur_state.strVAL_ONE = ""
						ur_state.intVAL_ONE = 0
					End Sub 'Reset_Symobls
				End Class 'prv
			End Class 'Loop_Valid

			Public Shared Function Loop_Return_Valid(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_Valid
				Dim retSTATE = New prv.Loop_Valid(ur_state, ur_new_symbol, ur_symbol_size)
				Loop_Return_Valid = retSTATE
				If retSTATE.strVAL_ONE <> "" Then
					If retSTATE.intVAL_ONE = 0 Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							If strLIST <> "" Then
								strLIST &= ", "
							End If

							strLIST &= strENTRY
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used in Roman numerals.")

					ElseIf retSTATE.strVAL_FOUR = retSTATE.strVAL_THREE AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_TWO AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_ONE Then
						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_FOUR & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & ur_new_symbol & "] is not valid: A single symbol may not be repeated more than three times.")

					ElseIf retSTATE.strVAL_TWO = retSTATE.strVAL_ONE AndAlso
					  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
							If Left(strENTRY_VAL, 1) = "1" Then
								If strLIST <> "" Then
									strLIST &= ", "
								End If

								strLIST &= strENTRY
							End If
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be repeated.")

					ElseIf retSTATE.strVAL_TWO <> "" Then
						If retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
							Dim strLIST = ""
							For Each strENTRY In ur_symbol_size.Keys
								Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
								If Left(strENTRY_VAL, 1) = "1" Then
									If strLIST <> "" Then
										strLIST &= ", "
									End If

									strLIST &= strENTRY
								End If
							Next strENTRY

							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used as the lower symbol followed by a higher symbol.")

						ElseIf retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  retSTATE.intVAL_ONE <> retSTATE.intVAL_TWO * 10 Then
							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: The lower symbol must be ten times less value than the following higher symbol.")

						ElseIf retSTATE.strVAL_THREE <> "" Then
							If retSTATE.intVAL_TWO > retSTATE.intVAL_ONE AndAlso
							  retSTATE.intVAL_ONE >= retSTATE.intVAL_THREE Then
								retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: A lower symbol followed by higher symbol must be followed by lower symbol than the first of the series.")
							End If
						End If 'strVAL_THREE
					End If 'strVAL_TWO
				End If 'strVAL_ONE
			End Function 'Loop_Return_Valid

			Public Shared Function Loop_Return_State(ur_state As prv.Loop_State, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_State
				Dim retSTATE = New prv.Loop_State
				Loop_Return_State = retSTATE

				Dim intNEW_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
				Dim intLOW_OR_HIGH_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_state.strLOW_OR_HIGH_TEMP)
				If ur_state.strLOW_OR_HIGH_TEMP = "" Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM
					retSTATE.enrSTATE = enmLH.low_or_high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol

				ElseIf intNEW_VALUE > intLOW_OR_HIGH_VALUE Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intNEW_VALUE - intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ""

				Else
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.low_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol
				End If
			End Function 'Loop_Return_State

			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function Numeral_To_Int(ur_symbol_size As Mx.sia, ur_numeral As String) As Integer
				Numeral_To_Int = 0
				If ur_symbol_size.ContainsKey(ur_numeral) Then
					Numeral_To_Int = ur_symbol_size.Item(ur_numeral)
				End If
			End Function 'Numeral_To_Int
		End Class 'prv
	End Class 'glblRomanNumeral

	Public Class sia
		Inherits System.Collections.Generic.Dictionary(Of String, Integer)
	End Class
End Namespace 'Mx

VBNS Project\Wiki_Move_HTM

TWCard Filter VBCode
<<ext "Wiki Move HTM">>

```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
End Function '2021m01d03
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Const strLIT_WIKI_MOVE_5_SEC = "Wiki Move 5-Sec"
        Const strvLIT_USER_PROFILE_DOWNLOADS = "%USERPROFILE%\downloads"
        Const strLIT_STAR_DOT_HTM = "WikiMove_*-stamp-*.htm"
        Const strLIT_STAR_DOT_HTML = "WikiMove_*-stamp-*.html"
        Const strLIT_STAR_DOT_CARDTXT = "WikiMove_*-stamp-*.card*.txt"

        Public Shared Sub UITimer_to_Poll_FileDir_And_Move(ur_ret As Strap)
            ur_ret.d("QUIT")
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            Dim strUI_FORM_TITLE = strLIT_WIKI_MOVE_5_SEC
            userbowl_cart.SelKey(uiform_title_bowlname).Contents = strUI_FORM_TITLE
            userbowl_cart.SelKey(enmUN.poll_folder).Contents = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)
            If glbl.gDiagnostics.IsRunningWindow(strUI_FORM_TITLE) Then
                glbl.gInteraction.AppActivate(strUI_FORM_TITLE)

            Else
                Dim objFORM = New Mx.WikiMove_Form()
                objFORM.Text = userbowl_cart.SelKey(enmUN.uiform_title).v(enmUB.contents)
                Call objFORM.Display_FolderList()
                objFORM.tmrFIVE_SEC.Start()
                Dim strNEW_DATA_FOLDER = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)

                'System.Windows.Forms.Application.Run(objFORM) only works from a command line program with no forms open. VBNetScript already has a form open.
                Call objFORM.ShowDialog()
            End If 'gDiagnostics
        End Sub 'UITimer_to_Poll_FileDir_And_Move

        Public Shared Function UITimer_to_Poll_FileDir_And_Move_errhnd(ur_commandline_text As String) As Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Strapd()
            UITimer_to_Poll_FileDir_And_Move_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call UITimer_to_Poll_FileDir_And_Move(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'UITimer_to_Poll_FileDir_And_Move_errhnd

        Public Shared Sub Poll_FileDir_And_Move(ur_ui_form As WikiMove_Form)
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            Dim windows_fs_cart = Have.WindowsFS
            Dim filemove_cart = Have.FileMove
            Call ur_ui_form.Display_FolderList()
            filemove_cart.DelAll()
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTM)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTML)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_CARDTXT)
            filemove_cart.Move_Files()
            Dim report_output_bowlname = userbowl_cart.Apply(filemove_cart)
            Dim strREPORT_OUTPUT = userbowl_cart.SelKey(report_output_bowlname).v(enmUB.contents)
            If HasText(strREPORT_OUTPUT) Then
                ur_ui_form.txtOUTPUT.Text = strREPORT_OUTPUT & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move

        Public Shared Sub Poll_FileDir_And_Move_errhnd(ur_ui_form As WikiMove_Form)
            Dim objERR_LIST = New ErrListBase : Try
                Call Poll_FileDir_And_Move(ur_ui_form:=ur_ui_form)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                ur_ui_form.txtOUTPUT.Text = objERR_LIST.ToString & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move_errhnd

        Public Class CombineTextOutput
            Public gText As Strap
            Public gFolderList As Sdata

            Public Sub New(ur_text As Strap, ur_folder_list As Sdata)
                Me.gText = ur_text
                Me.gFolderList = ur_folder_list
            End Sub
        End Class 'CombineTextOutput
    End Class 'sub_main

    Public Class WikiMove_Form
        Inherits System.Windows.Forms.Form

        Public tmrFIVE_SEC As System.Windows.Forms.Timer
        Public txtOUTPUT As System.Windows.Forms.TextBox
        Public intSHOW_FORM As Integer

        Public Sub New()
            Me.intSHOW_FORM = 1

            Me.Name = "Wiki_Move"
            Me.Size = New System.Drawing.Size(400, 400)
            Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen

            Me.txtOUTPUT = New System.Windows.Forms.TextBox()
            Me.txtOUTPUT.Name = "txtOUTPUT"
            Me.txtOUTPUT.Multiline = True
            Me.txtOUTPUT.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
            Me.txtOUTPUT.Dock = System.Windows.Forms.DockStyle.Fill
            Me.Controls.Add(Me.txtOUTPUT)

            Me.tmrFIVE_SEC = New System.Windows.Forms.Timer()
            Me.tmrFIVE_SEC.Interval = 50
            AddHandler Me.tmrFIVE_SEC.Tick, AddressOf Timer1_Tick
        End Sub 'New

        Sub Display_FolderList()
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            If HasText(Me.txtOUTPUT.Text) = False Then
                Me.txtOUTPUT.Text = Strapd().dLine("Listening:").dS(userbowl_cart.SelKey(pollfolder_bowlname).v(enmUB.contents)).dLine().d(Me.txtOUTPUT.Text)
            End If
        End Sub 'Display_FolderList

        Sub Look_For_Files()
            Call Mx.Want.Poll_FileDir_And_Move_errhnd(Me)
        End Sub

        Sub Show_Saved()
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            If Me.intSHOW_FORM = 1 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Normal
                Call AppActivate(userbowl_cart.SelKey(uiform_title_bowlname).v(enmUB.contents))
                Me.tmrFIVE_SEC.Interval = 800
                Me.intSHOW_FORM = 2

            ElseIf Me.intSHOW_FORM = 2 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Minimized
                Me.intSHOW_FORM = 0

            ElseIf Me.intSHOW_FORM = 0 Then
                If Me.WindowState <> System.Windows.Forms.FormWindowState.Minimized Then
                    Me.intSHOW_FORM = 6
                End If

            Else
                Me.intSHOW_FORM -= 1
            End If
        End Sub 'Show_Saved

        Sub Timer1_Tick(sender As Object, e As System.EventArgs)
            Me.tmrFIVE_SEC.Stop()
            Me.tmrFIVE_SEC.Interval = 5000
            Call Look_For_Files()
            Call Show_Saved()
            Me.tmrFIVE_SEC.Start()
        End Sub 'Timer1_Tick
    End Class 'WikiMove_Form




    Public Class Have
        Partial Class sFileMove
            Public Sub Apply(ur_windows_fs_cart As Have.glblWindowsFS, ur_userbowl_cart As Have.sUserBowl, ur_poll_folder_bowlname As enmUN, ur_filespec As String)
                Dim strPOLL_FOLDER = ur_userbowl_cart.SelKey(ur_poll_folder_bowlname).Contents
                For Each strFILE_PATH In ur_windows_fs_cart.GetFiles(strPOLL_FOLDER, ur_filespec, System.IO.SearchOption.TopDirectoryOnly)
                    Dim flnFILE_NAME = FileNamed().d(strFILE_PATH)
                    Dim sdaEXT_LIST = flnFILE_NAME.ExtList
                    Dim strDEST_PATH_ENCODED_IN_NAME = flnFILE_NAME.Name.Substring("WikiMove_".Length)
                    Dim strDEST_PATH = strDEST_PATH_ENCODED_IN_NAME.Replace("-colon-", ":").Replace("-fslash-", "\")
                    Dim intSTAMP = InStr(strDEST_PATH, "-stamp-")
                    strDEST_PATH = Left(strDEST_PATH, intSTAMP - 1)
                    Dim strEXT = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count))
                    If sdaEXT_LIST.Count > 1 Then
                        Dim strEXT2 = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count - 1))
                        If AreEqual(strEXT, ".txt") AndAlso
                          StartingWithText(strEXT2, ".card") Then
                            strEXT = ".card.txt"
                        End If
                    End If 'sdaEXT_LIST

                    strDEST_PATH &= strEXT
                    Me.Ins(
                        New rFileMove().
                        vt(enmFM.src_file_path, strFILE_PATH).
                        vt(enmFM.dest_file_path, strDEST_PATH)
                        )
                Next strFILE_PATH
            End Sub 'Apply ur_windows_fs_cart

            Public Sub Move_Files()
                Dim lstLEN = New System.Collections.Generic.List(Of Integer)
                For Each rowFILE In Me.SelAll
                    Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                    Dim intLEN = strFILE_PATH.Length
                    If lstLEN.Contains(intLEN) = False Then
                        lstLEN.Add(intLEN)
                    End If
                Next rowFILE

                Call lstLEN.Sort()
                For Each intLEN In lstLEN
                    For Each rowFILE In Me.SelAll
                        Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                        If strFILE_PATH.Length = intLEN Then
                            Dim strDEST_PATH = rowFILE.v(enmFM.dest_file_path)
                            glbl.gWindowsFS.Move(strFILE_PATH, strFILE_PATH & ".TDLY")
                            glbl.gWindowsFS.Delete(strDEST_PATH)
                            glbl.gWindowsFS.Move(strFILE_PATH & ".TDLY", strDEST_PATH)
                        End If 'strFILE_PATH
                    Next rowFILE
                Next intLEN
            End Sub 'Move_Files
        End Class 'sFileMove

        Partial Class sUserBowl
            Public Function Apply(ur_filemove_cart As sFileMove) As enmUN.zreport_output
                Dim retKEY = enmUN.report_output
                Apply = retKEY
                Dim stpREPORT = Strapd()
                For Each rowFILE In ur_filemove_cart.SelAll
                    stpREPORT.dLine(Now.ToString("tt hh:mm:ss")).d(":").dS(rowFILE.v(enmFM.dest_file_path))
                Next rowFILE

                Me.SelKey(retKEY).v(enmUB.contents) = stpREPORT
            End Function 'Apply(ur_filemove_cart
        End Class 'sUserBowl
    End Class 'Have



    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblFileMove As sFileMove
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblFileMove = New sFileMove
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmFM
        Inherits bitBASE
        Public Shared src_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
        Public Shared dest_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
    End Class

    Partial Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function FileMove() As sFileMove
            Call Have.Connect()
            FileMove = Have.tblFileMove
        End Function

        Public Class rFileMove
            Inherits TRow(Of enmFM)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmFM, ur_val As String) As rFileMove
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rFileMove

        Public Class sFileMove
            Private ttb As Objlist(Of rFileMove)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rFileMove)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub DelAll()
                Me.ttb.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rFileMove) As rFileMove
                Ins = ur_from
                Dim ttbSEL = Me
                Me.ttb.Add(ur_from)
            End Function 'Ins

            Public ReadOnly Property SelAll() As Objlist(Of rFileMove)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sFileMove
    End Class 'Have

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared poll_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared uiform_title As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function 'UserBowl

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = Have.WindowsMsgBox.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(strAUDIT)
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

View All Cards

$:/positivesigner/text-ref
<$list filter="[all[tiddlers]!tag[EXTLINK]!tag[IMG]!tag[INDEX]!tag[MCR]!tag[META]!has[draft.of]!is[image]!is[tag]!is[system]has[tags]!prefix[undefined]sort[title]]">
<hr>
<h2><$link to=<<currentTiddler>> /></h2>
{{||$:/core/ui/ViewTemplate/tags}}
<$transclude mode="block"/>
</$list>

View All Code

$:/positivesigner/text-ref
<$list variable=cur_card_pk filter="[!has[draft.of]!prefix[undefined]!prefix[$]] [prefix[$]!has[draft.of]has[tags]] +[sort[title]]">
<hr>
<h2><$link to=<<cur_card_pk>> /></h2>
<$list variable=cur_card_tags filter="[<cur_card_pk>tags[]]">
<<cur_card_tags>> 
</$list><!--cur_card_text-->
<$list variable=cur_card_text filter="[<cur_card_pk>get[text]]">
<$codeblock code=<<cur_card_text>> />
</$list><!--cur_card_text-->
</$list><!--cur_card_pk-->

WindowsCLI

DOC
<<glbl_article_list>>

WindowsCLI\Batch Replacement Parameters

WindowsCLI AssignVariable
"""
User Replacement Text = UrProgram

[Example.cmd file]
- SET CUR_DIR=%~dp0
- "%CUR_DIR%UrProgram.exe"

WindowsCLI\Command line hide Errors

WindowsCLI ErrorHandling
"""
[Windows CLI]
- [Turn off standard messages being echoed to the console]
- `@@ECHO OFF`

[https://docs.microsoft.com/en-us/troubleshoot/cpp/redirecting-error-command-prompt]
- To redirect the error message to NUL, use the following command:
"""

```
dir file.xxx 2> nul
```

"""
- You can print the errors and standard output to a single file by using the &1 command to redirect the output for STDERR to STDOUT and then sending the output from STDOUT to a file:
"""

```
dir file.xxx 1> output.msg 2>&1
```

WindowsCLI\Command list

WindowsCLI CodeLibrary
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands

"""

Prerequisites
The information that is contained in this topic applies to:Windows Server 2019

Windows Server (Semi-Annual Channel)

Windows Server 2016

Windows Server 2012 R2

Windows Server 2012

Windows Server 2008 R2

Windows Server 2008

Windows 10

Windows 8.1Command shell overview
The Command shell was the first shell built into Windows to automate routine tasks, like user account management or nightly backups, with batch (.bat) files. With Windows Script Host you could run more sophisticated scripts in the Command shell. For more information, see
cscript
or
wscript
. You can perform operations more efficiently by using scripts than you can by using the user interface. Scripts accept all Commands that are available at the command line.

Windows has two command shells: The Command shell and
PowerShell
. Each shell is a software program that provides direct communication between you and the operating system or application, providing an environment to automate IT operations.

PowerShell was designed to extend the capabilities of the Command shell to run PowerShell commands called cmdlets. Cmdlets are similar to Windows Commands but provide a more extensible scripting language. You can run Windows Commands and PowerShell cmdlets in Powershell, but the Command shell can only run Windows Commands and not PowerShell cmdlets.

For the most robust, up-to-date Windows automation, we recommend using PowerShell instead of Windows Commands or Windows Script Host for Windows automation.

Note

You can also download and install
PowerShell Core
, the open source version of PowerShell. Caution

Incorrectly editing the registry may severely damage your system. Before making the following changes to the registry, you should back up any valued data on the computer. Note

To enable or disable file and directory name completion in the Command shell on a computer or user logon session, run
regedit.exe
and set the following
reg_DWOrd value
:

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\completionChar\reg_DWOrd

To set the
reg_DWOrd
value, use the hexadecimal value of a control character for a particular function (for example,
0 9
is Tab and
0 08
is Backspace). User-specified settings take precedence over computer settings, and command-line options take precedence over registry settings.Command-line reference A-Z
To find information about a specific Windows Command, in the following A-Z menu, click the letter that the Command starts with, and then click the Command name.

A append
arp
assoc
at
atmadm
attrib
auditpol
autochk
autoconv
autofmt
B bcdboot
bcdedit
bdehdcfg
bitsadmin
bitsadmin addfile
bitsadmin addfileset
bitsadmin addfilewithranges
bitsadmin cancel
bitsadmin complete
bitsadmin create
bitsadmin getaclflags
bitsadmin getbytestotal
bitsadmin getbytestransferred
bitsadmin getcompletiontime
bitsadmin getcreationtime
bitsadmin getdescription
bitsadmin getdisplayname
bitsadmin geterror
bitsadmin geterrorcount
bitsadmin getfilestotal
bitsadmin getfilestransferred
bitsadmin getminretrydelay
bitsadmin getmodificationtime
bitsadmin getnoprogresstimeout
bitsadmin getnotifycmdline
bitsadmin getnotifyflags
bitsadmin getnotifyinterface
bitsadmin getowner
bitsadmin get priority
bitsadmin getproxybypasslist
bitsadmin getproxylist
bitsadmin getproxyusage
bitsadmin getreplydata
bitsadmin getreplyfilename
bitsadmin getreplyprogress
bitsadmin getstate
bitsadmin gettype
bitsadmin help
bitsadmin info
bitsadmin list
bitsadmin listfiles
bitsadmin monitor
bitsadmin nowrap
bitsadmin rawreturn
bitsadmin removecredentials
bitsadmin replaceremoteprefix
bitsadmin reset
bitsadmin resume
bitsadmin setaclflag
bitsadmin setcredentials
bitsadmin setdescription
bitsadmin setdisplayname
bitsadmin setminretrydelay
bitsadmin setnoprogresstimeout
bitsadmin setnotifycmdline
bitsadmin setnotifyflags
bitsadmin setpriority
bitsadmin setproxysettings
bitsadmin setreplyfilename
bitsadmin suspend
bitsadmin takeownership
bitsadmin Transfer
bitsadmin util
bitsadmin wrap bootcfg
bootcfg addsw
bootcfg copy
bootcfg dbg1394
bootcfg debug
  bootcfg default
bootcfg delete
bootcfg ems
bootcfg query
bootcfg raw
bootcfg rmsw
bootcfg timeout break
C cacls
call
cd
certreq
certutil
change
change logon
change port
change user chcp
chdir
chglogon
chgport
chgusr
chkdsk
chkntfs
choice
cipher
cleanmgr
clip
cls
Cmd
cmdkey
cmstp
color
comp
compact
convert
copy
cprofile
cscript
D date
dcgpofix
defrag
del
dfsrmig
diantz
dir
diskcomp
diskcopy
diskpart
diskperf
diskraid
diskshadow
dispdiag
dnscmd
doskey
driverquery
E echo
edit
endlocal
erase
eventcreate
eventquery
eventtriggers
evntcmd
exit
expand
extract
F fc
find
findstr
finger
flattemp
fondue
for
forfiles
format
freedisk
fsutil
fsutil 8dot3name
 fsutil behavior
 fsutil file
fsutil fsinfo
fsutil hardlink
fsutil objectid
fsutil quota
fsutil repair
fsutil reparsepoint
fsutil resource
fsutil sparse
fsutil tiering
fsutil transaction
fsutil usn
fsutil volume
fsutil wim ftp
ftype
fveupdate
G getmac
gettype
goto
gpfixup
gpresult
gpupdate
graftabl
H help
helpctr
hostname
I icacls
if
inuse
ipconfig
ipxroute
irftp
J jetpack
K klist
ksetup
ksetup:setrealm
ksetup:mapuser
ksetup:addkdc
ksetup:delkdc
ksetup:addkpasswd
ksetup:delkpasswd
ksetup:server
ksetup:setcomputerpassword
ksetup:removerealm
ksetup:domain
ksetup:changepassword
ksetup:listrealmflags
ksetup:setrealmflags
ksetup:addrealmflags
ksetup:delrealmflags
ksetup:dumpstate
ksetup:addhosttorealmmap
ksetup:delhosttorealmmap
ksetup:setenctypeattr
ksetup:getenctypeattr
ksetup:addenctypeattr
ksetup:delenctypeattr ktmutil
ktpass
L label
lodctr
logman
logman create
logman query
logman start &124; stop
logman delete
logman update
logman import &124; export logoff
lpq
lpr
M macfile
makecab
manage-bde
manage-bde: status
manage-bde: on
manage-bde: off
manage-bde: pause
manage-bde: resume
manage-bde: lock
manage-bde: unlock
manage-bde: autounlock
manage-bde: protectors
manage-bde: tpm
manage-bde: setidentifier
manage-bde: ForceRecovery
manage-bde: changepassword
manage-bde: changepin
manage-bde: changekey
manage-bde: KeyPackage
manage-bde: upgrade
manage-bde: WipeFreeSpace mapadmin
Md
mkdir
mklink
mmc
mode
more
mount
mountvol
move
mqbkup
mqsvc
mqtgsvc
msdt
msg
msiexec
msinfo32
mstsc
N nbtstat
netcfg
netsh
netstat
Net print
nfsadmin
nfsshare
nfsstat
nlbmgr
nslookup
nslookup exit command
nslookup finger command
nslookup help
nslookup ls
nslookup lserver
nslookup root
nslookup server
nslookup set
nslookup set all
nslookup set class
nslookup set d2
nslookup set debug
nslookup set domain
nslookup set port
nslookup set querytype
nslookup set recurse
nslookup set retry
nslookup set root
nslookup set search
nslookup set srchlist
nslookup set timeout
nslookup set type
nslookup set vc
nslookup view ntbackup
ntcmdprompt
ntfrsutl
O openfiles
P pagefileconfig
path
pathping
pause
pbadmin
pentnt
perfmon
ping
pnpunattend
pnputil
popd
PowerShell
PowerShell_ise
print
prncnfg
prndrvr
prnjobs
prnmngr
prnport
prnqctl
prompt
pubprn
pushd
pushprinterconnections
Q qappsrv
qprocess
query
quser
qwinsta
R rcp
rd
rdpsign
recover
reg
reg add
reg compare
reg copy
reg delete
reg export
reg import
reg load
reg query
reg restore
reg save
reg unload regini
regsvr32
relog
rem
ren
rename
repair-bde
replace
reset session
rexec
risetup
rmdir
robocopy
route_ws2008
rpcinfo
rpcping
rsh
rundll32
rwinsta
S schtasks
scwcmd
scwcmd: analyze
scwcmd: configure
scwcmd: register
scwcmd: rollback
 scwcmd: transform
 scwcmd: view
 

secedit
secedit:analyze
secedit:configure
secedit:export
secedit:generaterollback
secedit:import
secedit:validate serverceipoptin
Servermanagercmd
serverweroptin
set
setlocal
setx
sfc
shadow
shift
showmount
shutdown
sort
start
subst
sxstrace
sysocmgr
systeminfo
T takeown
tapicfg
taskkill
tasklist
tcmsetup
telnet
tftp
time
timeout
title
tlntadmn
tpmvscmgr
tracerpt
tracert
tree
tscon
tsdiscon
tsecimp
tskill
tsprof
type
typeperf
tzutil
U unlodctr
V ver
verifier
verify
vol
vssadmin
-W waitfor
wbadmin
wbadmin enable backup
wbadmin disable backup
wbadmin start backup
wbadmin stop job
wbadmin get versions
wbadmin get items
wbadmin start recovery
wbadmin get status
wbadmin get disks
wbadmin start systemstaterecovery
wbadmin start systemstatebackup
wbadmin delete systemstatebackup
wbadmin start sysrecovery
wbadmin restore catalog
wbadmin delete catalog wdsutil
wecutil
wevtutil
where
whoami
winnt
winnt32
winpop
winrs
wmic
wscript
X xcopy

WindowsCLI\Environment Variables

EnvironmentVariable WindowsCLI Extract
!! Windows CLI Environment Variable examples

<<ext "Windows Environment Variable List">>

* Environment variable %USERPROFILE%

User-replaced value = UrUserName

!! Show the Current Directory environment variable
* [Windows CLI]
* `ECHO %CD%`
* Press enter -> `C:\UrFolderPath\UrSubfolder`

!! Navigate to the C:\Users\UrUserName folder
* [Windows CLI]
* `cd %USERPROFILE%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName`

!! Navigate to the C:\Users\UrUserName\AppData\Local\Temp folder
* `cd %TEMP%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName\AppData\Local\Temp`

!! Navigate to the C:\Users\UrUserName\AppData\Roaming folder
* `cd %APPDATA%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName\AppData\Roaming`

WindowsCLI\Unicode characters

WindowsCLI Unicode Text WindowsOS
!! Use the standard Windows ANSI Character input
<<ext "Windows Alt-Numpad Unicode">>
* Hold down Alt key, then type the Decimal sequence using only the 0-9 on the Numeric Keypad
* Note: This only works for the 255 characters in the current Windows code page

!! Enable Alt-Numeric Keypad input of Unicode Characters
* Start `RegEdit.exe`
* Navigate to`HKEY_CURRENT_USER\Control Panel\Input Method`
!!
* [New String Value]
* name = `EnableHexNumpad`
* value = `1`
!!
* [Start Menu]
* Reboot your computer
!!
* [In any Windows program]
* Turn on `Numlock`

* Hold down `Alt`-key, then type the Numeric Keypad Plus (+) key once
* Still holding down the `Alt`-key, type the hexadecimal sequence using only the letters A-F on the main keyboard and 0-9 on the Numeric Keypad
* Release the `Alt`-key -> Windows pastes the Unicode character in the current program window
* Note: This may not work for 5-digit hexadecimal codes like U+1F937

!! Use the FileFormat.Info tool Unicode Input

<<ext "FileFormat.Info UnicodeInput">>

[In any program]
* Hold down 'Alt'-key, then type the Numeric Keypad Plus (+) key -> Opens dialog box
* Note: The `U+` displayed in the window means "Enter a Unicode character number in hexadecimal format"
* Type in a hexadecimal number
* Press enter -or- Click button Send -> Closes window, types desired Unicode character in foreground window

<<ext "FileFormat.Info UnicodeInput.ZIP">>

* Note: This EXE program is able to be started from anywhere
* Note: Closing the window minimizes to the system tray as `blue circle with white lowercase letter i`

!! Display Unicode UTF-8 characters in Windows CLI

* [In some UrProgram.cmd file or Command Prompt window]
* First put the line: `@chcp 65001>nul`
* Stream UTF-8 characters from files to the Command Prompt window -> Unicode characters are shown correctly
* Note: If you do not change the code page, Unicode characters will be split into as High- and Low-ASCII characters from the current Windows code page

<<ext "WindowsCLI Unicode Support">>
* HEX input delivers a character on KeyUp of Alt; all the other ways to deliver a character happen on KeyDown; so many applications are not ready to see a character on KeyUp. (Only applicable to applications using Console-I/O API.)
* Conclusion: Many application would not react on HEX input events.
* Note: Unless your keyboard layout supports input of A LOT of characters without prefix keys, some buggy applications may skip characters when you Paste via Console’s UI
!!
* One should also keep in mind that the “alternative, ‘more capable’ consoles” for Windows are not consoles at all. They do not support Console-I/O APIs, so the programs which rely on these APIs to work would not function. (The programs which use only “File-I/O APIs to the console filehandles” would work fine, though.)
* Note: One example of such non-console is a part of MicroSoft’s Powershell. 

!! Change the default Codepage of Windows console
* [RegEdit.exe]
* Navigate to `HKEY_CURRENT_USER\Software\Microsoft\Command Processor`
!!
* [New String Value]
* Name = `Autorun`
* Value = `chcp 65001`
!!
* Actually, the trick is that the command prompt actually understands these non-english characters, just can't display them correctly
* Note: When I enter a path in the command prompt that contains some non-english chracters it is displayed as "?? ?????? ?????"
* Note:  When you submit your command (cd "??? ?????? ?????" in my case), everything is working as expected

!! <<ext "Windows Terminal Unicode Support">>
* Windows Terminal is a new, modern, fast, efficient, powerful, and productive terminal application for users of command-line tools and shells like Command Prompt, PowerShell, and WSL.

YouTube

DOC
<<glbl_article_list>>

YouTube\Captions text

YouTube ClosedCaptions Extract
!! Export closed captions text file from a YouTube video page
* Note: Android O/S will need to show the YouTube page as a Desktop Site
!!
* [Top-right icons]
* Click the three-dots menu, option Desktop site -> Reloads page
!!
* [Below video, Right-side icons]
* Click the three-dots menu, option Open Transcript -> Navigates page below video or right-side of video
* You can highlight the captions text and copy to the clipboard
* Note: You can paste the captions text into a document and save or print them

!! Find closed captions text file in YouTube video HTML content on Windows
* Type Ctrl-A to Select all text on the page
* Paste all text into a new text document
* At the top of the file, search down for "00:" to find the first line of the captions text
* Delete all text above this line
!!
* At the bottom of the file, search up for "00:" to find the last line of the captions text
* Delete all text below this line
* The remaining lines are the closed captions file

!! Find closed captions text file in YouTube video HTML content on Android O/S
* Search for "views" or [the video title] to find the end of the captions text


WindowsCLI\Batch Replacement Parameters

AssignVariable WindowsCLI

User Replacement Text = UrProgram

[Example.cmd file]
- SET CUR_DIR=%~dp0
- "%CUR_DIR%UrProgram.exe"


WindowsCLI\Command line hide Errors

ErrorHandling WindowsCLI

[Windows CLI]
- [Turn off standard messages being echoed to the console]
- @@ECHO OFF

[https://docs.microsoft.com/en-us/troubleshoot/cpp/redirecting-error-command-prompt]
- To redirect the error message to NUL, use the following command:

dir file.xxx 2> nul

- You can print the errors and standard output to a single file by using the &1 command to redirect the output for STDERR to STDOUT and then sending the output from STDOUT to a file:

dir file.xxx 1> output.msg 2>&1

WindowsCLI\Command list

CodeLibrary WindowsCLI

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands


Prerequisites
The information that is contained in this topic applies to:Windows Server 2019

Windows Server (Semi-Annual Channel)

Windows Server 2016

Windows Server 2012 R2

Windows Server 2012

Windows Server 2008 R2

Windows Server 2008

Windows 10

Windows 8.1Command shell overview
The Command shell was the first shell built into Windows to automate routine tasks, like user account management or nightly backups, with batch (.bat) files. With Windows Script Host you could run more sophisticated scripts in the Command shell. For more information, see
cscript
or
wscript
. You can perform operations more efficiently by using scripts than you can by using the user interface. Scripts accept all Commands that are available at the command line.

Windows has two command shells: The Command shell and
PowerShell
. Each shell is a software program that provides direct communication between you and the operating system or application, providing an environment to automate IT operations.

PowerShell was designed to extend the capabilities of the Command shell to run PowerShell commands called cmdlets. Cmdlets are similar to Windows Commands but provide a more extensible scripting language. You can run Windows Commands and PowerShell cmdlets in Powershell, but the Command shell can only run Windows Commands and not PowerShell cmdlets.

For the most robust, up-to-date Windows automation, we recommend using PowerShell instead of Windows Commands or Windows Script Host for Windows automation.

Note

You can also download and install
PowerShell Core
, the open source version of PowerShell. Caution

Incorrectly editing the registry may severely damage your system. Before making the following changes to the registry, you should back up any valued data on the computer. Note

To enable or disable file and directory name completion in the Command shell on a computer or user logon session, run
regedit.exe
and set the following
reg_DWOrd value
:

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\completionChar\reg_DWOrd

To set the
reg_DWOrd
value, use the hexadecimal value of a control character for a particular function (for example,
0 9
is Tab and
0 08
is Backspace). User-specified settings take precedence over computer settings, and command-line options take precedence over registry settings.Command-line reference A-Z
To find information about a specific Windows Command, in the following A-Z menu, click the letter that the Command starts with, and then click the Command name.

A append
arp
assoc
at
atmadm
attrib
auditpol
autochk
autoconv
autofmt
B bcdboot
bcdedit
bdehdcfg
bitsadmin
bitsadmin addfile
bitsadmin addfileset
bitsadmin addfilewithranges
bitsadmin cancel
bitsadmin complete
bitsadmin create
bitsadmin getaclflags
bitsadmin getbytestotal
bitsadmin getbytestransferred
bitsadmin getcompletiontime
bitsadmin getcreationtime
bitsadmin getdescription
bitsadmin getdisplayname
bitsadmin geterror
bitsadmin geterrorcount
bitsadmin getfilestotal
bitsadmin getfilestransferred
bitsadmin getminretrydelay
bitsadmin getmodificationtime
bitsadmin getnoprogresstimeout
bitsadmin getnotifycmdline
bitsadmin getnotifyflags
bitsadmin getnotifyinterface
bitsadmin getowner
bitsadmin get priority
bitsadmin getproxybypasslist
bitsadmin getproxylist
bitsadmin getproxyusage
bitsadmin getreplydata
bitsadmin getreplyfilename
bitsadmin getreplyprogress
bitsadmin getstate
bitsadmin gettype
bitsadmin help
bitsadmin info
bitsadmin list
bitsadmin listfiles
bitsadmin monitor
bitsadmin nowrap
bitsadmin rawreturn
bitsadmin removecredentials
bitsadmin replaceremoteprefix
bitsadmin reset
bitsadmin resume
bitsadmin setaclflag
bitsadmin setcredentials
bitsadmin setdescription
bitsadmin setdisplayname
bitsadmin setminretrydelay
bitsadmin setnoprogresstimeout
bitsadmin setnotifycmdline
bitsadmin setnotifyflags
bitsadmin setpriority
bitsadmin setproxysettings
bitsadmin setreplyfilename
bitsadmin suspend
bitsadmin takeownership
bitsadmin Transfer
bitsadmin util
bitsadmin wrap bootcfg
bootcfg addsw
bootcfg copy
bootcfg dbg1394
bootcfg debug
bootcfg default
bootcfg delete
bootcfg ems
bootcfg query
bootcfg raw
bootcfg rmsw
bootcfg timeout break
C cacls
call
cd
certreq
certutil
change
change logon
change port
change user chcp
chdir
chglogon
chgport
chgusr
chkdsk
chkntfs
choice
cipher
cleanmgr
clip
cls
Cmd
cmdkey
cmstp
color
comp
compact
convert
copy
cprofile
cscript
D date
dcgpofix
defrag
del
dfsrmig
diantz
dir
diskcomp
diskcopy
diskpart
diskperf
diskraid
diskshadow
dispdiag
dnscmd
doskey
driverquery
E echo
edit
endlocal
erase
eventcreate
eventquery
eventtriggers
evntcmd
exit
expand
extract
F fc
find
findstr
finger
flattemp
fondue
for
forfiles
format
freedisk
fsutil
fsutil 8dot3name
fsutil behavior
fsutil file
fsutil fsinfo
fsutil hardlink
fsutil objectid
fsutil quota
fsutil repair
fsutil reparsepoint
fsutil resource
fsutil sparse
fsutil tiering
fsutil transaction
fsutil usn
fsutil volume
fsutil wim ftp
ftype
fveupdate
G getmac
gettype
goto
gpfixup
gpresult
gpupdate
graftabl
H help
helpctr
hostname
I icacls
if
inuse
ipconfig
ipxroute
irftp
J jetpack
K klist
ksetup
ksetup:setrealm
ksetup:mapuser
ksetup:addkdc
ksetup:delkdc
ksetup:addkpasswd
ksetup:delkpasswd
ksetup:server
ksetup:setcomputerpassword
ksetup:removerealm
ksetup:domain
ksetup:changepassword
ksetup:listrealmflags
ksetup:setrealmflags
ksetup:addrealmflags
ksetup:delrealmflags
ksetup:dumpstate
ksetup:addhosttorealmmap
ksetup:delhosttorealmmap
ksetup:setenctypeattr
ksetup:getenctypeattr
ksetup:addenctypeattr
ksetup:delenctypeattr ktmutil
ktpass
L label
lodctr
logman
logman create
logman query
logman start &124; stop
logman delete
logman update
logman import &124; export logoff
lpq
lpr
M macfile
makecab
manage-bde
manage-bde: status
manage-bde: on
manage-bde: off
manage-bde: pause
manage-bde: resume
manage-bde: lock
manage-bde: unlock
manage-bde: autounlock
manage-bde: protectors
manage-bde: tpm
manage-bde: setidentifier
manage-bde: ForceRecovery
manage-bde: changepassword
manage-bde: changepin
manage-bde: changekey
manage-bde: KeyPackage
manage-bde: upgrade
manage-bde: WipeFreeSpace mapadmin
Md
mkdir
mklink
mmc
mode
more
mount
mountvol
move
mqbkup
mqsvc
mqtgsvc
msdt
msg
msiexec
msinfo32
mstsc
N nbtstat
netcfg
netsh
netstat
Net print
nfsadmin
nfsshare
nfsstat
nlbmgr
nslookup
nslookup exit command
nslookup finger command
nslookup help
nslookup ls
nslookup lserver
nslookup root
nslookup server
nslookup set
nslookup set all
nslookup set class
nslookup set d2
nslookup set debug
nslookup set domain
nslookup set port
nslookup set querytype
nslookup set recurse
nslookup set retry
nslookup set root
nslookup set search
nslookup set srchlist
nslookup set timeout
nslookup set type
nslookup set vc
nslookup view ntbackup
ntcmdprompt
ntfrsutl
O openfiles
P pagefileconfig
path
pathping
pause
pbadmin
pentnt
perfmon
ping
pnpunattend
pnputil
popd
PowerShell
PowerShell_ise
print
prncnfg
prndrvr
prnjobs
prnmngr
prnport
prnqctl
prompt
pubprn
pushd
pushprinterconnections
Q qappsrv
qprocess
query
quser
qwinsta
R rcp
rd
rdpsign
recover
reg
reg add
reg compare
reg copy
reg delete
reg export
reg import
reg load
reg query
reg restore
reg save
reg unload regini
regsvr32
relog
rem
ren
rename
repair-bde
replace
reset session
rexec
risetup
rmdir
robocopy
route_ws2008
rpcinfo
rpcping
rsh
rundll32
rwinsta
S schtasks
scwcmd
scwcmd: analyze
scwcmd: configure
scwcmd: register
scwcmd: rollback
scwcmd: transform
scwcmd: view


secedit
secedit:analyze
secedit:configure
secedit:export
secedit:generaterollback
secedit:import
secedit:validate serverceipoptin
Servermanagercmd
serverweroptin
set
setlocal
setx
sfc
shadow
shift
showmount
shutdown
sort
start
subst
sxstrace
sysocmgr
systeminfo
T takeown
tapicfg
taskkill
tasklist
tcmsetup
telnet
tftp
time
timeout
title
tlntadmn
tpmvscmgr
tracerpt
tracert
tree
tscon
tsdiscon
tsecimp
tskill
tsprof
type
typeperf
tzutil
U unlodctr
V ver
verifier
verify
vol
vssadmin
-W waitfor
wbadmin
wbadmin enable backup
wbadmin disable backup
wbadmin start backup
wbadmin stop job
wbadmin get versions
wbadmin get items
wbadmin start recovery
wbadmin get status
wbadmin get disks
wbadmin start systemstaterecovery
wbadmin start systemstatebackup
wbadmin delete systemstatebackup
wbadmin start sysrecovery
wbadmin restore catalog
wbadmin delete catalog wdsutil
wecutil
wevtutil
where
whoami
winnt
winnt32
winpop
winrs
wmic
wscript
X xcopy


WindowsCLI\Environment Variables

EnvironmentVariable Extract WindowsCLI

Windows CLI Environment Variable examples

Windows Environment Variable List

->

  • Environment variable %USERPROFILE%

User-replaced value = UrUserName

Show the Current Directory environment variable

  • [Windows CLI]
  • ECHO %CD%
  • Press enter -> C:\UrFolderPath\UrSubfolder

Navigate to the C:\Users\UrUserName folder

  • [Windows CLI]
  • cd %USERPROFILE%
  • Press enter
  • cd
  • Press enter -> C:\Users\UrUserName

Navigate to the C:\Users\UrUserName\AppData\Local\Temp folder

  • cd %TEMP%
  • Press enter
  • cd
  • Press enter -> C:\Users\UrUserName\AppData\Local\Temp

Navigate to the C:\Users\UrUserName\AppData\Roaming folder

  • cd %APPDATA%
  • Press enter
  • cd
  • Press enter -> C:\Users\UrUserName\AppData\Roaming

WindowsCLI\Unicode characters

Text Unicode WindowsCLI WindowsOS

Use the standard Windows ANSI Character input

Windows Alt-Numpad Unicode

->

  • Hold down Alt key, then type the Decimal sequence using only the 0-9 on the Numeric Keypad
  • Note: This only works for the 255 characters in the current Windows code page

Enable Alt-Numeric Keypad input of Unicode Characters

  • Start RegEdit.exe
  • Navigate toHKEY_CURRENT_USER\Control Panel\Input Method

  • [New String Value]
  • name = EnableHexNumpad
  • value = 1

  • [Start Menu]
  • Reboot your computer

  • [In any Windows program]
  • Turn on Numlock
  • Hold down Alt-key, then type the Numeric Keypad Plus (+) key once
  • Still holding down the Alt-key, type the hexadecimal sequence using only the letters A-F on the main keyboard and 0-9 on the Numeric Keypad
  • Release the Alt-key -> Windows pastes the Unicode character in the current program window
  • Note: This may not work for 5-digit hexadecimal codes like U+1F937

Use the FileFormat.Info tool Unicode Input

FileFormat.Info UnicodeInput

->

[In any program] * Hold down 'Alt'-key, then type the Numeric Keypad Plus (+) key -> Opens dialog box * Note: The U+ displayed in the window means "Enter a Unicode character number in hexadecimal format" * Type in a hexadecimal number * Press enter -or- Click button Send -> Closes window, types desired Unicode character in foreground window

FileFormat.Info UnicodeInput.ZIP

->

  • Note: This EXE program is able to be started from anywhere
  • Note: Closing the window minimizes to the system tray as blue circle with white lowercase letter i

Display Unicode UTF-8 characters in Windows CLI

  • [In some UrProgram.cmd file or Command Prompt window]
  • First put the line: @chcp 65001>nul
  • Stream UTF-8 characters from files to the Command Prompt window -> Unicode characters are shown correctly
  • Note: If you do not change the code page, Unicode characters will be split into as High- and Low-ASCII characters from the current Windows code page

WindowsCLI Unicode Support

->

  • HEX input delivers a character on KeyUp of Alt; all the other ways to deliver a character happen on KeyDown; so many applications are not ready to see a character on KeyUp. (Only applicable to applications using Console-I/O API.)
  • Conclusion: Many application would not react on HEX input events.
  • Note: Unless your keyboard layout supports input of A LOT of characters without prefix keys, some buggy applications may skip characters when you Paste via Console’s UI

  • One should also keep in mind that the “alternative, ‘more capable’ consoles” for Windows are not consoles at all. They do not support Console-I/O APIs, so the programs which rely on these APIs to work would not function. (The programs which use only “File-I/O APIs to the console filehandles” would work fine, though.)
  • Note: One example of such non-console is a part of MicroSoft’s Powershell.

Change the default Codepage of Windows console

  • [RegEdit.exe]
  • Navigate to HKEY_CURRENT_USER\Software\Microsoft\Command Processor

  • [New String Value]
  • Name = Autorun
  • Value = chcp 65001

  • Actually, the trick is that the command prompt actually understands these non-english characters, just can't display them correctly
  • Note: When I enter a path in the command prompt that contains some non-english chracters it is displayed as "?? ?????? ?????"
  • Note: When you submit your command (cd "??? ?????? ?????" in my case), everything is working as expected

Windows Terminal Unicode Support
->

  • Windows Terminal is a new, modern, fast, efficient, powerful, and productive terminal application for users of command-line tools and shells like Command Prompt, PowerShell, and WSL.

YouTube\Captions text

ClosedCaptions Extract YouTube

Export closed captions text file from a YouTube video page

  • Note: Android O/S will need to show the YouTube page as a Desktop Site

  • [Top-right icons]
  • Click the three-dots menu, option Desktop site -> Reloads page

  • [Below video, Right-side icons]
  • Click the three-dots menu, option Open Transcript -> Navigates page below video or right-side of video
  • You can highlight the captions text and copy to the clipboard
  • Note: You can paste the captions text into a document and save or print them

Find closed captions text file in YouTube video HTML content on Windows

  • Type Ctrl-A to Select all text on the page
  • Paste all text into a new text document
  • At the top of the file, search down for "00:" to find the first line of the captions text
  • Delete all text above this line

  • At the bottom of the file, search up for "00:" to find the last line of the captions text
  • Delete all text below this line
  • The remaining lines are the closed captions file

Find closed captions text file in YouTube video HTML content on Android O/S

  • Search for "views" or [the video title] to find the end of the captions text

View All Code

6th March 2021 at 8:07pm
$:/positivesigner/text-ref


$:/config/MissingLinks

$:/positivesigner/base-install
no

$:/config/Navigation/openLinkFromOutsideRiver

$:/positivesigner/base-install
bottom

$:/config/Navigation/Permalinkview/CopyToClipboard

$:/positivesigner/base-install
no

$:/config/ShortcutInfo/font-large

$:/positivesigner/text-ref

$:/config/ShortcutInfo/font-normal

$:/positivesigner/text-ref

$:/config/ShortcutInfo/home-tiddlers

$:/positivesigner/home-button

$:/config/ShortcutInfo/save-all-changes

$:/positivesigner/base-install

$:/config/shortcuts/font-large

$:/positivesigner/text-ref
ctrl-shift-Quote

$:/config/shortcuts/font-normal

$:/positivesigner/text-ref
ctrl-shift-Comma

$:/config/shortcuts/home-tiddlers

$:/positivesigner/home-button
alt-H

$:/config/shortcuts/save-all-changes

$:/positivesigner/base-install
alt-S

$:/config/TextEditor/EnableToolbar

$:/positivesigner/text-ref
no

$:/config/ViewToolbarButtons/Visibility/$:/positivesigner/gcmpr/btn gcmpr card

$:/positivesigner/gcmpr
hide

$:/config/WikiParserRules/Inline/wikilink

$:/positivesigner/base-install
disable

$:/DefaultTiddlers

$:/positivesigner/base-install
[tag[INDEX]has[sort_ord]sort[title]]
[tag[INDEX]!has[sort_ord]sort[title]]

$:/language/DefaultNewTiddlerTitle

$:/positivesigner/base-install
New Card

$:/positivesigner/base-install

$:/positivesigner/base-install $:/positivesigner/gcmpr $:/positivesigner/home-button $:/positivesigner/text-ref $:/positivesigner/div-pop
\define show_pill()
<<tag-pill tag:"$(cur_entry)$" >>
\end
---
<$list variable=cur_entry filter="[prefix[$:/positivesigner/]is[tag]sort[]]">

<<cur_entry>>
</$list>

$:/positivesigner/div-pop

$:/positivesigner/base-install $:/positivesigner/div-pop

$:/positivesigner/gcmpr

$:/positivesigner/gcmpr $:/positivesigner/base-install

$:/positivesigner/gcmpr/btn gcmpr card

$:/tags/ViewToolbar $:/positivesigner/gcmpr
<<gcmpr_btn_cmp_current>> 

$:/positivesigner/gcmpr/mcr gcmpr_compare_card

$:/tags/Macro $:/positivesigner/gcmpr
\define gcmpr_compare_card(ur_ttb_card)
<$list variable=ttb_card filter="[[$ur_ttb_card$]!match[]]">
<$list variable=compare_card filter="[<ttb_card>addprefix[$:/state/popup/compare-card/]]">
<$link to=<<ttb_card>> />
<<gcmpr_ref_edit_source_text>>
<<gcmpr_ref_copy_over_ttb_card>>
<br>
<$link to=<<compare_card>> />
<<gcmpr_ref_replace_comment_endings>>
<<gcmpr_ref_disp_diff_text>>
<$edit-text autoHeight=no tiddler=<<compare_card>> tag=textarea default="" />
<<gcmpr_ref_disp_textedit_link>>
</$list><!--compare_card-->
</$list><!--ttb_card-->
<!--gcmpr_compare_card-->
\end

\define gcmpr_ref_edit_source_text(ttb_card, compare_card)
<$vars enr_text="text" >
<$list variable=source_text filter="[<ttb_card>get<enr_text>else[]]">
<$button>
<$action-setfield $tiddler=<<compare_card>> text=<<source_text>> />
Copy Source
</$button>
</$list><!--source_text-->
</$vars><!--enr_text-->
<!--gcmpr_ref_edit_source_text-->
\end

\define gcmpr_ref_copy_over_ttb_card(ttb_card, compare_card)
<$vars enr_text="text" >
<$list variable=compare_text filter="[<compare_card>get<enr_text>else[]]">
<$button>
<$action-setfield $tiddler=<<ttb_card>> text=<<compare_text>> />
Overwrite Source
</$button>
</$list><!--compare_text-->
</$vars><!--enr_text-->
<!--gcmpr_ref_copy_over_ttb_card-->
\end

\define gcmpr_ref_replace_comment_endings(ttb_card, compare_card)
<$button>
<$vars comment_flag="--" lit_exclm="!" lit_lt="<" lit_gt=">" enr_text="text" >
<$wikify name=lit_lf text="&#10;">
<$list variable=comment_open_text filter="[<lit_lt>addsuffix<lit_exclm>addsuffix<comment_flag>]">
<$list variable=comment_close_text filter="[<comment_flag>addsuffix<lit_gt>]">
<$list variable=comment_close_replace filter="[<comment_flag>addsuffix<lit_exclm>addsuffix<lit_gt>]">
<$list variable=replace_text filter="[<compare_card>get<enr_text>split<comment_close_text>join<comment_close_replace>addprefix<lit_lf>addprefix<comment_open_text>addsuffix<lit_lf>addsuffix<comment_close_text>]">
<$action-setfield $tiddler=<<compare_card>> text=<<replace_text>> />
</$list><!--replace_text-->
</$list><!--comment_close_replace-->
</$list><!--comment_close_text-->
</$list><!--comment_open_text-->
</$wikify>
</$vars><!--comment_flag, lit_exclm, lit_lt, lit_gt-->
Replace comment endings
</$button><br>
<!--gcmpr_ref_replace_comment_endings-->
\end

\define gcmpr_ref_disp_diff_text()
<$list variable=val_ttb_card filter="[<ttb_card>get[text]!match[]]">
<$list variable=val_compare_card filter="[<compare_card>get[text]!match[]]">
<$diff-text source=<<val_ttb_card>> dest=<<val_compare_card>> />
</$list><!--val_compare_card-->
</$list><!--val_ttb_card-->
<!--gcmpr_ref_disp_diff_text-->
\end

\define gcmpr_ref_disp_textedit_link()
<$list variable=cur_url filter="[{$:/info/url/full}]">
<$list variable=new_link filter="[<cur_url>addsuffix[#]addsuffix[$:/positivesigner/gcmpr/textarea]split[$:]join[%24%3A]]">
<a href=<<new_link>> target="_blank" >text editor</a>
</$list>
</$list>
<!--gcmpr_ref_disp_textedit_link-->
\end

\define gcmpr_btn_cmp_current()
<$list variable=cur_card filter="[all[current]]">
<$list variable=dest_card filter="[<cur_card>addprefix[$:/state/popup/gcmpr/]]">
<$vars lit_lt="<" lit_gt=">" lit_s=" " lit_qs='"' macro_name="gcmpr_compare_card" enr_text="text" >
<$list variable=macro_call_text filter="[<lit_lt>addsuffix<lit_lt>addsuffix<macro_name>addsuffix<lit_s>addsuffix<lit_qs>addsuffix<cur_card>addsuffix<lit_qs>addsuffix<lit_gt>addsuffix<lit_gt>]">
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler=<<dest_card>> text=<<macro_call_text>> />
<$action-navigate $to=<<dest_card>> />
Compare to Textbox
</$button>
</$list><!--macro_call_text-->
</$vars><!--lit_lt-->
</$list><!--dest_card-->
</$list><!--cur_card-->
<!--gcmpr_btn_cmp_current-->
\end

\define gcmpr_textarea_new()
<$vars enr_text="text" enr_new_filename="new_filename" enr_rows="rows" enr_cols="cols" enr_disp_btn_incr_decr="disp_btn_incr_decr" lit_state_popup_prefix="$:/state/popup/gcmpr_textarea/" lit_default_rows="20" lit_default_cols="160" cur_card=<<currentTiddler>> >
<$list variable=temp_card filter="[<cur_card>addprefix<lit_state_popup_prefix>]">
New file name:
@@margin-left:5px;
<$edit-text tiddler=<<temp_card>> field=new_filename placeholder="" autoHeight=yes tag=input/>
@@
<$list variable=val_disp_btn_incr_decr filter="[<temp_card>get<enr_disp_btn_incr_decr>!match[]else[]]">
<$list variable=val_rows filter="[<temp_card>get<enr_rows>!match[]!match[0]else<lit_default_rows>]">
<$list variable=val_cols filter="[<temp_card>get<enr_cols>!match[]!match[0]else<lit_default_cols>]">
<$list variable=val_new_filename filter="[<temp_card>get<enr_new_filename>!match[]]">
<$list variable=new_card filter="[<val_new_filename>addprefix<lit_state_popup_prefix>]">
<$list variable=new_temp_card filter="[<new_card>addprefix<lit_state_popup_prefix>]">
<$list variable=filter_newcard_not_exists filter="[<new_card>!is[tiddler]]">
<$button>
<$list variable=cur_card_text filter="[<cur_card>get<enr_text>]">
<$action-setfield $tiddler=<<new_card>> $field=<<enr_text>> $value=<<cur_card_text>> />
</$list><!--cur_card_text-->
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_new_filename>> $value=<<val_new_filename>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_rows>> $value=<<val_rows>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_cols>> $value=<<val_cols>> />
<$action-setfield $tiddler=<<new_temp_card>> $field=<<enr_disp_btn_incr_decr>> $value=<<val_disp_btn_incr_decr>> />
<$action-navigate $to=<<new_card>> />
New card
</$button>
</$list><!--filter_newcard_not_exists-->
</$list><!--new_temp_card-->
</$list><!--new_card-->
</$list><!--val_new_filename-->

<br>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>!match[]]">
@@margin-right:20px;
<$button>
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_disp_btn_incr_decr>> $value="" />
Show Resize buttons
</$button>
@@
</$list><!--filter_disp_buttons-->
Rows: <<val_rows>>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>match[]]">
<$button>
<$list variable=val_new_rows filter="[<val_rows>add[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_rows>> $value=<<val_new_rows>> 
/>
</$list><!--val_new_rows-->
+
</$button>
<$list variable=filter_zero_rows filter="[<val_rows>!match[0]]">
<$button>
<$list variable=val_new_rows filter="[<val_rows>subtract[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_rows>> $value=<<val_new_rows>> />
</$list><!--val_new_rows-->
-
</$button>
</$list><!--filter_zero_rows-->
</$list><!--filter_disp_buttons-->
Cols: <<val_cols>>
<$list variable=filter_disp_buttons filter="[<val_disp_btn_incr_decr>match[]]">
<$button>
<$list variable=val_new_cols filter="[<val_cols>add[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_cols>> $value=<<val_new_cols>> />
</$list><!--val_new_cols-->
+
</$button>
<$list variable=filter_zero_cols filter="[<val_cols>!match[0]]">
<$button>
<$list variable=val_new_cols filter="[<val_cols>subtract[10]]">
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_cols>> $value=<<val_new_cols>> />
</$list><!--val_new_cols-->
-
</$button>
@@margin-left:20px;
<$button>
<$action-setfield $tiddler=<<temp_card>> $field=<<enr_disp_btn_incr_decr>> $value="hide" />
Hide resize buttons
</$button>
@@
</$list><!--filter_disp_buttons-->
</$list><!--filter_zero_cols-->
<br>
<textarea rows=<<val_rows>> cols=<<val_cols>> />
</$list><!--val_cols-->
</$list><!--val_rows-->
</$list><!--val_disp_btn_incr_decr-->
</$list><!--temp_card-->
</$vars><!--enr_new_filename-->
\end

\define glbl_chk(ur_field)
<br><$checkbox tiddler=<<currentTiddler>> field="$ur_field$" unchecked="no" checked="yes"></$checkbox><span style="margin-right:5px;" />
\end

$:/positivesigner/gcmpr/textarea

$:/positivesigner/gcmpr
<<gcmpr_textarea_new>>

$:/positivesigner/home-button

$:/positivesigner/home-button $:/positivesigner/base-install

$:/positivesigner/text-ref

$:/positivesigner/base-install $:/positivesigner/text-ref

$:/themes/tiddlywiki/vanilla/options/sidebarlayout

$:/positivesigner/base-install
fluid-fixed

AndroidChromeBrowser

DOC
<<glbl_article_list>>

AndroidChromeBrowser\Desktop Shortcut to Website

AndroidOS Browser FileSystem
"""
This does not work for file:///sdcard HTML files
Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Google Chrome app]
- [Non-incognito mode]
- Navigate to website page
- Note: This does not work for file:///sdcard HTML files
- [Top-right icons]
- Click the three-lines menu, option Add to Home screen -> Opens dialog
- [Add to Home screen dialog]
- Shortcut name / UrShortcutName
- Click button Add -> Closes dialog

[Desktop icons]
- Click icon UrShortcutName -> Opens browser

AndroidGit

DOC
<<glbl_article_list>>

AndroidGit\Pocket Git pull repository updates

AndroidOS GitCode FileSystem UserAction
"""
[Pocket Git app]
- [Repositories List page, Top-right icons]
- Click button Preferences (looks like three lines) -Navigates page
- [Preferences page, Defaults section]
- Click link Default Directory -> Opens dialog
- [Select Folder dialog]
- Select the Downloads folder -> Closes dialog
- [Preferences page, Defaults section]
- Note: Default Directory = /storage/emulated/0/Download
- Click button Back (looks like a left arrow) -> Navigates page

- [Repositories List page, Bottom-right icons]
- Click button Create Project (looks like a red button with a Plus sign) -> Opens dialog
- [Create Project dialog]
- Project Name = UrProjectName
- Clone URL = UrRepositoryURL
- Note: Local Path automatically creates a sub-directory under the Downloads folder
- Click the Authentication drop-list, option Password
- Username = UrRepositoryUsername
- Password = UrRepositoryPassword
- [Create Project dialog, Top-right icons]
- Click button Save (looks like a floppy disk) -> Closes dialog

- [Repositories List page]
- Click repository UrProjectName -> Navigates page

- [Repository page, Top-right icons]
- Click the Remotes menu (looks like a cloud), click option Fetch -> Starts process
- Wait for popup message "Finished fetching"
- Click the Remotes menu, click option Pull -> Starts process
- Wait for popup message "Finished pulling"

[File system]
- [Downloads folder]
- Note: All the files in the repository are available under the UrProjectName sub-folder in the Downloads folder

AndroidMultipleUsers

DOC
<<glbl_article_list>>

AndroidMultipleUsers\Common access files

AndroidOS FileSystem UserAction
"""
When you change users on an Android device, the file:///sdcard/ folder is aliased to a different location for each. There is a specific sub-folder that is aliased to the same location for all users.

[File Manager]
- Navigate to /sdcard/Android/obb
- Create a folder and copy files into it

[Android Notices menu]
- Change the current user

[File Manager]
- Navigate to /sdcard/Android/obb
- You can see the same folder and files from the other login

AndroidProgramming

DOC
<<glbl_article_list>>

AndroidProgramming\DCoder

AndroidOS VBCode FileSystem
Note: I found that the DCoder app actually submitted the VB code to a web server. So there was no way for me to access the local file system.

```
  'Visual Basic.Net Compiler version 0.0.0.5943 (Mono 4.0.1)

Imports System
Imports System.Collections.Generic
Imports System.Text.RegularExpressions

Namespace Dcoder
  Public Module Program
    Public Sub Main(args() As string)
      Dim strRET = "Hi"
      For Each strENTRY As String In SubDir_List("/")
          For Each strE2 As String In SubDir_List("/" & strENTRY)
          For Each strE3 As String In SubDir_List("/" & strENTRY)
              strRET &= vbLf & strENTRY & "/" & strE2 & "/" & strE3
          Next strE3
          Next strE2
      Next strENTRY
      
      strRET &= vbLf & "Done"
      Console.WriteLine(strRET)
    End Sub 'Main

    Public Function t1(ur_root_dir As String) As String
        Return "no"
    End Function

    Public Function SubDir_List(ur_root_dir As String) As System.Collections.Generic.List(Of String)
      Dim lstRET = New System.Collections.Generic.List(Of String)
      SubDir_List = lstRET
      Try
      Dim proc = New System.Diagnostics.Process
      Dim stg = new System.Diagnostics.ProcessStartInfo
      proc.StartInfo = stg
      stg.FileName = "ls"
      stg.Arguments = ur_root_dir

      'stg.FileName = "find"
      'stg.Arguments = ". -name '*' -print"

      stg.UseShellExecute = false
      stg.RedirectStandardOutput= true
      stg.RedirectStandardError = true
      stg.CreateNoWindow = true
      proc.Start()
      Dim strCL_OUT = proc.StandardOutput.ReadToEnd()
      'strRET = "[Output: " & vbLf & strCL_OUT & "]"
      'strRET &= vbLf & "(err: " & vbLf & proc.StandardError.ReadToEnd() & ")"
      For Each strENTRY As String In strCL_OUT.Split(CHR(10))
          If strENTRY <> "" Then
              lstRET.Add(strENTRY)
          End If
      Next strENTRY
      Catch ex As System.Exception
      End Try
    End Function 'SubDir_List
  End Module
End Namespace

AndroidQLua

DOC
<<glbl_article_list>>

AndroidQLua\Console Commands

AndroidOS LuaCode CodeLibrary
"""
[QLua app]
- Click button Console -> Navigates page

- [console window]
- Note: The right-arrow symbol (greater-than sign) is the Lua prompt
- Note: Comment line-endings in a Lua file are separated by two hyhpens
"""

```
--Single-line comment
ur_object.ur_function() --Comment until end of line
```

"""
- Note: Multi-line comments in a Lua file are separated by two hyphens and two open brackets, and closed by two hyphens and two close brackets
"""

```
--[[
Block comment
multiple lines
--]]
```

"""
- Note: Commands in Lua are case sensitive
- - You can create functions named `abc`, `Abc`, `abC`, and `ABC`, and each one can store to a different value

- Note: Exiting the Lua interpreter returns to the Linux Shell command line interpreter that was created by QLua
- Run the `os.exit()` command
"""

```
os.exit()
```

"""
[Linux Shell CLI]
- Note: The $ symbol (dollar sign) is the Linux Shell prompt
- Note: Commands in Linux Shell are case sensitive
- - You can create programs named `abc`, `Abc`, `abC`, and `ABC`, and each one can run different code
- - Most standard Linux Shell commands are named with all lowercase characters, so only `abc` would be the standard way to name a program

- Note: Exiting the Linux Shell returns to the QLua app main page
- Run the `exit` command
"""

```
exit
```


AndroidQLua\Console Run a Program

AndroidOS LuaCode UserAction
"""
[Lua console]
- Note: I had problems using the `LoadString` function with the `loadfile` command
- - In the Lua code, replace any references to the `LoadString` function with the `Load` function
- - The `Load` command did not need extra escaping like`\\r` for the parameter, so replace `\\r` with `\r` when using the `Load` command
- Save the result of the loadfile command to create a new function from the file
"""

```
urfile_fn=loadfile('/sdcard/qlua5/ur_file.lua')
```

"""
- Note: This added a row to the _G table
- Note: Just typing a function name or a table name shows the type of data stored in the row
"""

```
_G.urfile
```

"""
- Output is `function: 0x#####`
- Note: any command except _G is an implied name lookup in the _G table
"""

```
urfile
```

"""
- Output is also the same `function: 0x####`
- Note: You can run a function by adding parentheses to the end of the function name
- Running a function can load additional functions into the _G table
"""

```
urfile()
```

"""
- Output is the Lua program output
- Note: Any functions or tables added to the _G table are available
- Note: You can load a Lua function and run it on the same line instead of storing the program in a variable by adding an extra pair of parentheses
"""

```
loadfile('/sdcard/qlua5/ur_file.lua')()
```

"""
- Output is the Lua program output

AndroidQLua\Deploy a Program Module

AndroidOS LuaCode FileSystem
"""
Note: The `share/5.3` directory under the QLua5 folder is where Lua looks to load "program modules" that must be loaded to the _G array as a prerequisites to running the current program

[QLua Editor]
- Note: I had problems using the `LoadString` function with the `require` command
- - In the Lua code, replace any references to the `Load` function with the `LoadString` function
- - The `LoadString` command needs extra escaping like`\\r` for the parameter, so replace `\r` with `\\r` when using the `LoadString` command

- [Bottom bar]
- Click button Save-As (Looks like a page with a Plus in the bottom-right corner) -> Open dialog

- [Save As dialog]
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = `share`
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder `share`
- If necessary,
- - [Bottom bar]
- - Click button New Folder (looks like a Plus sign) -> Opens dialog
- - Directory Name = `5.3`
- - Click button OK -> Closes dialog

- [Folder list]
- Select folder `5.3`
- [Bottom bar]
- File name = UrFileName.lua
- Click button OK (looks like a checkmark)

[File Manager]
- Note: Your Lua program is stored in folder `/sdcard/qlua/share/5.3`

[Lua console]
- Note: The require command to loads and runs a program module
- - Do not include the path or the `.lua` file extension
"""

```
require 'UrFileName'
```

"""
- Output is the Lua program output

AndroidQLua\Editor Run a Program

AndroidOS LuaCode UserAction
"""
[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icon]
- Click button Open file (looks like a Tabbed folder) -> Opens dialog
- Select file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Note: You can change the source code and save again before each run

- [Bottom bar icons]
- Click button Run (looks like a right-arrow play button) -> Navigates page

- [console window]
- Note: The top line shows the current path and the Linux shell command used to show the editor
- Note: The output of your program is below the first line
- Note: The the last line says "Press enter to exit"

AndroidQLua\MxClasses Design

AndroidOS LuaCode FileSystem AssignVariable
"""
I created some default functions that I need to see the key/value pairs in Lua tables

[def.lua]
- [def_tcompile]
- This creates a 'tcompile' function that concatenates a table's string values then loads the result as a new function
- [def_ti]
- This creates a 'ti' function that adds a new numbered row to a table
- [def_tia]
- This clears out a global table variable and creates a 'tia' function that calls the 'ti' function for that table without having to pass it in as a parameter
- [def_printk]
- This creates a 'printk' function that prints all the keys in a table, sorted alphabetically
- [def_printv]
- This creates a 'printv' function that prints all the values in a table, sorted alphabetically
- [def_tcopy]
- This creates a 'tcopy' function that copies all records from one table into another
- [def_printiv]
- This creates a 'printiv' function that prints all the values in a table, in their original order (good for numeric-keyed tables)
- [def_printkv]
- This creates a 'printkv' function that prints all keys and values in a table, sorted by key alphabetically
- [def_ioexec]
- This creates a 'ioexec' function that runs a shell command and returns a table you can store
    - Example: Prints all the .lua files under a directory
"""

```
local ttbFILE = ioexec('find /sdcard/qlua5 -name "*.lua" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)
```

- [def_printio]
- This creates a 'printio' function that runs printiv on the ioexec table
    - Example: printio('ls /storage')

AndroidQLua\MxClasses LoadFile

AndroidOS LuaCode CodeLibrary FileSystem
```
--[under folder /sdcard/qlua5]
--This file can be run by the QLua command "LoadFile" because it uses the Load function instead of the LoadString function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) load(table.concat(ur_table, "\\r"))() end'}
load(table.concat(def_tcompile, "\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  load(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)

AndroidQLua\MxClasses Require Program Module

AndroidOS LuaCode CodeLibrary
```
--[under folder /sdcard/qlua5]
--Create subdir share/5.3
--Put in a copy of def.lua
--This file can be run by the QLua command "require" because it uses the LoadString function instead of the Load function in def_tcompile and def_tia

print()

def_tcompile = {'function tcompile(ur_table) loadstring(table.concat(ur_table, "\\r"))() end'}
loadstring(table.concat(def_tcompile, "\\r"))()

def_ti = {'function ti(ur_table, ur_line) table.insert(ur_table, ur_line) end'}
tcompile(def_ti)

def_tia = {}
ti(def_tia, 'function tia(ur_table)')
ti(def_tia, '  local strASSIGN = ur_table .. " = {}; " ')
ti(def_tia, '  strASSIGN = strASSIGN .. "function tii(ur_line) ti(" .. ur_table .. ", ur_line) end" ')
ti(def_tia, '  loadstring(strASSIGN)() ')
ti(def_tia, '  end')
tcompile(def_tia)

tia 'def_printk'
tii 'function printk(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printk)

tia 'def_printv'
tii 'function printv(ur_table)'
tii '  local pk = {}'
tii '  for k,v in pairs(ur_table) do'
tii '    table.insert(pk, v)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v) end'
tii '  end'
tcompile(def_printv)

tia 'def_tcopy'
tii 'function tcopy(ur_src_table, ur_dest_table)'
tii '  for k,v in pairs(ur_src_table) do'
tii '    table.insert(ur_dest_table, v)'
tii '    end'
tii '  end'
tcompile(def_tcopy)

tia 'def_printiv'
tii 'function printiv(ur_table)'
tii '  for k,v in pairs(ur_table) do'
tii '    print(v)'
tii '    end'
tii '  end'
tcompile(def_printiv)

tia 'def_printkv'
tii 'function printkv(ur_table)'
tii '  local pk = {}'
tii '  for k in pairs(ur_table) do'
tii '    table.insert(pk, k)'
tii '    end'
tii '  table.sort(pk)'
tii '  for k,v in pairs(pk) do print(v .. ": " .. type(ur_table[v]) ) end'
tii '  end'
tcompile(def_printkv)

tia 'def_ioexec'
tii 'function ioexec(ur_cmd)'
tii '  local iofile = io.popen(ur_cmd)'
tii '  local retTABLE = {}'
tii '  for k in iofile:lines() do table.insert(retTABLE, k) end'
tii '  iofile:close()'
tii '  return retTABLE'
tii '  end'
tcompile(def_ioexec)

tia 'def_printio'
tii 'function printio(ur_cmd)'
tii '  printiv(ioexec(ur_cmd))'
tii '  end'
tcompile(def_printio)

--printio('ls /storage')
--[[
local ttbFILE = ioexec('find /sdcard/Download -name "TWMove_*.htm" -print')
local strFILE = ""
for k,v in pairs(ttbFILE) do
  strFILE = v
  break
  end

print('1: ' .. strFILE)
--]]

AndroidQLua\Source Code Editor

AndroidOS LuaCode UserAction
"""
[QLua app]
- Click button Editor -> Navigates page

- [QLua app, Editor page, Top-right side icons]
- Click button New File (looks like a page with a Plus sign) -> Opens dialog

- [New file dialog]
- Click option Blank file -> Closes dialog

- [QLua app, Editor page, Main Body text]
- Enter some text

- [Bottom bar]
- Click button Save (looks like a 3.5" floppy disk)

[SDCard file list]
- Note: The file gets saved in the folder /sdcard/qlua5

AndroidScreenshot

DOC
<<glbl_article_list>>

AndroidScreenshot\Screenshot Easy

AndroidOS Video Extract
"""
[Google Play Store app]
- Install app Screenshot Easy by Ice Cold Apps
- Note: Contains ads

AndroidVNC

DOC
<<glbl_article_list>>

AndroidVNC\RealVNC remote control Windows O/S

AndroidOS Video UserAction WindowsOS
"""
Windows O/S

[https://www.realvnc.com/en/connect/download/viewer/windows/]
- Install app VNC Connect for Windows

[VNC Connect for Windows app]
- Connects to login
- Note: Allows connection by RealVNC's VNC Viewer app on Android O/S

Android O/S

[Google Play Store]
- Install app VNC Viewer by RealVNC Limited

[VNC Viewer app]
- Connects to login
- [Alt tab]
- Use Ctrl-Esc to get to the Windows Start Menu and the Task Bar to change windows

AndroidVNC\Remote Control Android Device

AndroidOS UserAction Video
"""
Install app AnyDesk by AnyDesk Software GmbH
- https://play.google.com/store/apps/details?id=com.anydesk.anydeskandroid&hl=en_US&gl=US

Install on both Android devices
- The other installed devices will show when connected to the same WiFi network
- Automatically figures out how to use the controlling Android device's touch screen

AndroidWebDav

DOC
<<glbl_article_list>>

AndroidWebDav\BestDAV

AndroidOS FileSystem UserAction
"""
Access files on Android device from a networked Windows computer

[Andrdoid OS]
- [Google Play Store]
- Install app WebDAV Server - BestDAV
- - Free or Pro edition

[WebDAV Server]
- [Main page, top bar]
- Note: Folders not listed under the "Folders" button automatically has read-only access via WebDav
- Click button Settings -> nav
- [Settings page]
- Website Home Directory = /storage
- [Main page, bottom bar]
- Click button Start Server
- Note: The server's network URL starts with "http://" and ends with ":8080"
- - Sample = http://192.168.0.15:8080

[Windows computer]
- [browser]
- Address = http://192.168.0.15:8080
- Click link Get the file list -> nav
- Note: The directory shows the "external" SD Card name (if any) and "enc_emulated"
- To see the "internal" /sdcard folder on the android device,
- - Click link "enc_emulated" -> /_dir.cgi?dir=%2Fenc_emulated
- - Edit the address to say /_dir.cgi?dir=%2Femulated/0

- [Windows Explorer]
- Address = \\192.168.0.15@8080\DavWWWRoot
- Note: The directory shows the "external" SD Card name (if any) and "emulated", "enc_emulated", and "self"
- To see the "internal" /sdcard folder on the android device,
- - Click link "emulated" -> http://192.168.0.15:8080/emulated
- - Edit the address to say http://192.168.0.15:8080/emulated/0

btn Delete Cards

$:/positivesigner/base-install
<$button>
<$list filter="[tag[ARTICLE]] [tag[IMG]]"><$action-deletetiddler $tiddler=<<currentTiddler>> /></$list>
Del ARTICLE and IMG cards
</$button>

Card filter

INDEX
\define tag_button(ur_field, ur_tag_name)
<$button>
<$action-setfield $tiddler="$ur_field$" text="$ur_tag_name$"/>
<$action-navigate $to="Tag pairs"/>
<<tag-pill "$ur_tag_name$">>
</$button>
\end

{{ext TW Return}}

<$list variable=on_twcard filter="[<tv-config-toolbar-icons>!match[no]]">
<$button>
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/tag_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/text_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
<$list variable=cur_temp_card filter="[prefix[$:/state/popup/text_input_e]]" >
<$action-deletetiddler $tiddler=<<cur_temp_card>> />
</$list><!--cur_temp_card-->
Clear filters
</$button><br>

Text search: <$edit-text tiddler="$:/state/popup/text_input_e1" field=text default="" placeholder="[Type to search for text 1]" autoHeight=yes tag=input/>
<$edit-text tiddler="$:/state/popup/text_input_e2" field=text default="" placeholder="[Type to search for text 2]" autoHeight=yes tag=input/>
<$button>
<$action-setfield $tiddler="$:/state/popup/text_e1" text={{$:/state/popup/text_input_e1}}/>
<$action-setfield $tiddler="$:/state/popup/text_e2" text={{$:/state/popup/text_input_e2}}/>
Search text
</$button><br>

<$list variable=text_prefix_e1 filter="[[$:/state/popup/text_e1]get[text]else[]]">
<$list variable=text_lowercase_e1 filter="[<text_prefix_e1>lowercase[]]">
<$list variable=text_prefix_e2 filter="[[$:/state/popup/text_e2]get[text]else[]]">
<$list variable=text_lowercase_e2 filter="[<text_prefix_e2>lowercase[]]">
<$list variable=tag_prefix_e1 filter="[[$:/state/popup/tag_e1]get[text]uppercase[]else[]]">
<$list variable=count_any_input filter="[<text_prefix_e1>] [<text_prefix_e2>] [<tag_prefix_e1>] +[each:value[]!match[]count[]]">

<$list variable=tag_list filter="[tags[]each:value[]!prefix[$:]sort[]]">
<$list variable=all_caps_taglist filter="[<tag_list>uppercase[]]">
<$list variable=filter_all_capslist filter="[<tag_list>!match<all_caps_taglist>]">
<$list variable=card_count filter="[tag<tag_list>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>count[]!match[0]]">@@white-space:nowrap;<$macrocall $name=tag_button ur_field="$:/state/popup/tag_e1" ur_tag_name=<<tag_list>> /> ( <<card_count>> )@@
</$list><!--card_count-->
</$list><!--filter_all_capslist-->
</$list><!--all_caps_taglist-->
</$list><!--tag_list
-->

<$list variable=filter_any_input filter="[<count_any_input>!match[0]]">
<$list variable=tag_e1 filter="[search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>tags[]each:value[]!prefix[$:]sort[]]">
<$list variable=all_caps_tage1 filter="[<tag_e1>uppercase[]]">
<$list variable=filter_all_capse1 filter="[<tag_e1>!match<all_caps_tage1>]">
<$list variable=filter_prefix_e1 filter="[<all_caps_tage1>prefix<tag_prefix_e1>]">
<$list variable=card_count filter="[tag<tag_e1>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>count[]]">
<$list variable=filter_card_found filter="[<card_count>!match[0]]">
<$macrocall $name=tag_button ur_field="$:/state/popup/tag_e1" ur_tag_name=<<tag_e1>> />

<$list variable=link_title filter="[tag<tag_e1>search:text,title<text_prefix_e1>search:text,title<text_prefix_e2>]">

<<<
<$link to=<<link_title>> /> (<$list variable=disp_tag filter="[<link_title>tags[]sort[]]"> <<disp_tag>> </$list>)

<$list variable=filter_anytext_e1 filter="[<text_prefix_e1>!match[]]">
<$list variable=found_leadingtext_e1 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e1>butlast[]]">

* <$list variable=sample_leadingtext_e1 filter="[<found_leadingtext_e1>split[ ]last[7]join[ ]]">
<$text text=<<sample_leadingtext_e1>> />
''<$text text=<<text_lowercase_e1>> />''
</$list><!--sample_leadingtext_e1-->
<br>
</$list><!--found_leadingtext_e1-->
<$list variable=found_trailingtext_e1 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e1>butfirst[]]">

* <$list variable=sample_trailingtext_e1 filter="[<found_trailingtext_e1>split[ ]first[7]join[ ]]">
''<$text text=<<text_lowercase_e1>> />''
<$text text=<<sample_trailingtext_e1>> />
</$list><!--sample_trailingtext_e1-->
</$list><!--found_trailingtext_e1-->
</$list><!--filter_anytext_e1
-->

<$list variable=filter_anytext_e2 filter="[<text_prefix_e2>!match[]]">
<$list variable=found_leadingtext_e2 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e2>butlast[]]">

* <$list variable=sample_leadingtext_e2 filter="[<found_leadingtext_e2>split[ ]last[7]join[ ]]">
<$text text=<<sample_leadingtext_e2>> />
''<$text text=<<text_lowercase_e2>> />''
</$list><!--sample_leadingtext_e2-->
<br>
</$list><!--found_leadingtext_e2-->
<$list variable=found_trailingtext_e2 filter="[<link_title>get[text]lowercase[]split<text_lowercase_e2>butfirst[]]">

* <$list variable=sample_trailingtext_e2 filter="[<found_trailingtext_e2>split[ ]first[7]join[ ]]">
''<$text text=<<text_lowercase_e2>> />''
<$text text=<<sample_trailingtext_e2>> />
</$list><!--sample_trailingtext_e2-->
</$list><!--found_trailingtext_e2-->
</$list><!--filter_anytext_e2
-->

<<<
</$list><!--link_title-->
</$list><!--filter_card_found-->
</$list><!--card_count-->
</$list><!--filter_prefix_e1-->
</$list><!--filter_all_capse1-->
</$list><!--all_caps_tage1-->
</$list><!--tag_e1-->
</$list><!--filter_any_input-->
</$list><!--count_any_input-->
</$list><!--tag_prefix_e1-->
</$list><!--text_lowercase_e2-->
</$list><!--text_lowercase_e1-->
</$list><!--text_prefix_e2-->
</$list><!--text_prefix_e1-->
</$list><!--on_twcard-->

[[Search All Code |View All Code]]

[[___|Recent Entries]]

ChromeBrowser

DOC
<<glbl_article_list>>

ChromeBrowser\Browse Local Folders

Browser FileSystem Extract
"""
Note: You can use Total Commander to create a local file desktop shortcut
Note: You can also create a Website shortcut on the Desktop from Google Chrome

[Google Chrome app]
- [Windows O/S]
- Navigate to file:///C:/
- [Android O/S]
- Navigate to file:///sdcard/

- [Directory list]
- Select which sub-folder you want to bookmark
- [Navigation bar, Top-right icons]
- Click button Bookmark Page (looks like a star shape) -> Opens dialog
- [Bookmark Added dialog]
- Name = UrShortName
- Click button Done -> Closes dialog
- [Navigation bar]
- Address = UrShortName -> Shows suggestions
- [Suggestion list]
- Select the suggested link -> Navigates page

ChromeBrowser\Command Line Options

Browser AssignVariable CodeLibrary
"""
The command line options are usually two hyphens followed by a keyword

- Note: The incognito option starts the browser with an open Incognito window
"""

```
–incognito
```

"""
- Note: Google Chrome Portable has these parameters automatically included when calling the Chrome.exe program.
"""

```
–user-data-dir="%TEMP%"
–disk-cache-dir="%TEMP%\GoogleChromePortable\Cache"
```

"""
To override the user data and all the cache directories:

- Find the INI file in the PortableApp sub-directory
"""

```
GoogleChromePortable\Other\Source\GoogleChromePortable.ini
```

"""
- Copy it to the program main directory
"""

```
GoogleChromePortable\GoogleChromePortable.ini
```

"""
- [Edit the file]
- CacheInTemp = false
- Save file
- Note: When you restart Google Chrome Portable, cached files will be stored under the program's folder
"""

```
C:\TJBF\zPortableInstalls\Chrome\Data\profile\Default\*Cache\
```

ChromeBrowser\Turn off Chrome spell check highlighting

Browser CodeLibrary Text Formatting
"""
[Google Chrome app]
- [Top-right icons]
- Click the three-dots menu, option Settings -> Navigates page
- [Settings page[
- search for Language -> Filters results
- [Languages section]
- checkbox Spell check = clear -> Chrome will not highlight spelling errors

Code Samples

INDEX
{{ext TW Return}}

<<list-links filter:"[tag[DOC]sort[title]]">>

[[___|Recent Entries]]

css alternating-rows

$:/tags/Stylesheet META
.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}

DivPop btn

$:/tags/ViewToolbar $:/positivesigner/div-pop
<$list variable=cur_card filter="[all[current]]">
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=<<cur_card>>/>
<$action-sendmessage $message="tm-close-tiddler" $param="pop_right"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{DivPop.svg}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text="Popup over Sidebar"/></span>
</$list>
</$button>
</$list>

DivPop glbl

$:/tags/BelowStory $:/positivesigner/div-pop
<$list variable=cur_divpop_card filter="[{$:/state/popup/DivPopTitle}is[tiddler]]">
<div style="
position: fixed;
top: 0px;
right: 0px;
width: 350px;
border: 3px solid;
background: white;
bottom: 0%;
">
<div style="overflow-y: scroll; height: 100%;">
<$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
close
</$button>
&nbsp;&nbsp;&nbsp;<$reveal type="match" state="$:/state/popup/$ur_pk$" text="show"><$button set="$:/state/popup/$ur_pk$" setTo="hide">show</$button>&nbsp;&nbsp;&nbsp;<$link to=<<cur_divpop_card>> ><<cur_divpop_card>>
</$link>
<$list variable=cur_text filter="[<cur_divpop_card>get[text]]">
<$codeblock code=<<cur_text>> /></$list>
</$reveal>
<$reveal type="nomatch" state="$:/state/popup/$ur_pk$" text="show"><$button set="$:/state/popup/$ur_pk$" setTo="show">code</$button>&nbsp;&nbsp;&nbsp;<$link to=<<cur_divpop_card>> ><<cur_divpop_card>>
</$link>
<$tiddler tiddler=<<cur_divpop_card>> >
<$transclude mode="block" />
</$tiddler>
</$reveal>
</div>
</div>
</$list>

DivPop.svg

$:/positivesigner/div-pop
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
   sodipodi:docname="PopupSidebar.svg"
   id="svg52"
   version="1.1"
   height="22pt"
   width="22pt"
   viewBox="0 0 128 128"
   class="tc-image-close-button tc-image-button">
  <metadata
     id="metadata58">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <defs
     id="defs56">
    <inkscape:perspective
       id="perspective60"
       inkscape:persp3d-origin="64 : 36.371105 : 1"
       inkscape:vp_z="128 : 43.054765 : 1"
       inkscape:vp_y="0 : 313.29655 : 0"
       inkscape:vp_x="0 : 43.054765 : 1"
       sodipodi:type="inkscape:persp3d" />
  </defs>
  <sodipodi:namedview
     inkscape:current-layer="svg52"
     inkscape:window-maximized="0"
     inkscape:window-y="27"
     inkscape:window-x="61"
     inkscape:cy="12.415296"
     inkscape:cx="21.019608"
     inkscape:zoom="8"
     showgrid="false"
     id="namedview54"
     inkscape:window-height="480"
     inkscape:window-width="820"
     inkscape:pageshadow="2"
     inkscape:pageopacity="0"
     guidetolerance="10"
     gridtolerance="10"
     objecttolerance="10"
     borderopacity="1"
     bordercolor="#666666"
     pagecolor="#ffffff" />
  <g
     id="g50"
     fill-rule="evenodd" />
  <rect
     y="13.090909"
     x="10.909091"
     height="104.72727"
     width="111.27273"
     id="rect85"
     style="fill:#cccccc;stroke-width:4.36364" />
  <rect
     y="19.636366"
     x="19.09091"
     height="89.454567"
     width="95.454552"
     id="rect92"
     style="fill:#ffffff;stroke-width:4.36364" />
  <rect
     y="58.909092"
     x="50.727272"
     height="10.909091"
     width="42.545452"
     id="rect94"
     style="fill:#cccccc;stroke-width:4.36364" />
  <path
     id="path96"
     d="m 61.090909,34.363636 c 32.181818,24.545458 32.181818,24.545458 32.181818,24.545458 v 0"
     style="fill:#cccccc;stroke:#cccccc;stroke-width:4.36364px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
  <path
     id="path98"
     d="M 64.909091,95.999999 C 93.272727,69.818185 93.272727,69.818185 93.272727,69.818185"
     style="fill:#b3b3b3;stroke:#cccccc;stroke-width:4.36364px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
  <rect
     y="16.90909"
     x="86.727272"
     height="94.909088"
     width="8.181818"
     id="rect100"
     style="fill:#cccccc;stroke-width:4.36364" />
</svg>

Excel VBA

DOC
<<glbl_article_list>>

Excel VBA\Get Worksheet

ExcelCode CodeLibrary FileSystem
```
Dim wksDATA As Worksheet
Set wksDATA = Application.ActiveSheet
wksDATA.Cells(2,2).Value = "Hi"

'Press F5 to run the macro
'Note: Cell B2 says "Hi"

Excel VBA\New Macro

ExcelCode FileSystem AssignVariable
"""
[Microsoft Excel application]
- [Ribbon menus]
- View menu, option Record Macro -> Starts recording
- View menu, option Stop Recording -> Stops recording
- View menu, option Macros -> Opens dialog

[Macro list]
- Click button Edit Macro -> Opens window

[VBA Editor]
- You can change the name of the macro and add commands
- Close the editor

[Microsoft Excel application]
- Save the file as a Macro-Enabled workbook (mwb)

Excel VBA\Power Exponent

ExcelCode Numbers Extract
"""
Make sure you put a space between the power operator (^) and the numbers

- CalcResult = 2^5
- Note: This gives a compilation error on 64-bit Excel

- CalcResult = 2 ^ 5
- Note: CalcResult = 32

ext ALAorg Citations bookmarklet

EXT
http://www.ala.org/tools/article/ala-techsource/%E2%80%9Ccitethis%E2%80%9D-building-javascript-bookmarklet-creates-citations-sharing-web

ext Apple.com Safari Meta tags

EXT
https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html

ext CodeAcademy DocType

EXT
https://discuss.codecademy.com/t/why-we-type-before-doctype-what-is-the-role-of-in-doctype-html/60880/3

ext DeveloperSettings HTM

EXT
VBNet_Project\DeveloperSettings\Developer Settings App.html

ext DeveloperSettings ZIP

EXT
VBNet_Project\DeveloperSettings\DeveloperSettings.zip

ext Empty Wiki Setup

EXT
TW Project\Empty Wiki\Empty Wiki.htm

ext FileFormat.Info UnicodeInput

EXT
https://www.fileformat.info/tool/unicodeinput/index.htm

ext FileFormat.Info UnicodeInput.ZIP

EXT
https://www.fileformat.info/tool/unicodeinput/unicodeinput.zip

ext GitHub LukeHorvat Computed Style to Inline

EXT
https://github.com/lukehorvat/computed-style-to-inline-style

ext GoogleDevelopers FullScreen web app

EXT
https://developers.google.com/web/fundamentals/native-hardware/fullscreen/

ext HTML.com DocType

EXT
https://html.com/tags/doctype/

ext JavaScript Closures

EXT
http://blog.niftysnippets.org/2008/02/closures-are-not-complicated.html

ext JavaScript Strict Mode

EXT
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

ext JavaScript This Parameter

EXT
http://blog.niftysnippets.org/2008/03/mythical-methods.html

ext JTFAssociates MOTW

EXT
https://jtfassociates.com/using-the-mark-of-the-web-motw/

ext MathiasBynens Rel Icon

EXT
https://mathiasbynens.be/notes/rel-shortcut-icon

ext MetaTags.org Generator

EXT
https://www.metatags.org/all-meta-tags-overview/meta-name-generator/

ext Microsoft DotNet Char ConvertToUTF32

EXT
https://docs.microsoft.com/en-us/dotnet/api/system.char.converttoutf32?view=net-5.0#System_Char_ConvertToUtf32_System_String_System_Int32_

ext Microsoft RemoteDesktop Enable

EXT
https://docs.microsoft.com/en-us/windows-server/remote/remote-desktop-services/clients/remote-desktop-allow-access

ext Mozilla.org META tags

EXT
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta/name

ext MozillaDeveloper CSS Comment

EXT
https://developer.mozilla.org/en-US/docs/Web/CSS/Comments

ext MozillaDeveloper Strict mode

EXT
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

ext MxBase Classes

EXT
VBNet_Project/MxBase/MxBase%20Classes.html

ext Project Check app

EXT
TW Project\Checkapp\Checkapp.htm

ext PSU.edu LangTag

EXT
https://accessibility.psu.edu/foreignlanguages/langtaghtml/

ext Regexp Filter with brackets

EXT
https://tiddlywiki.narkive.com/T5403O4p/tw5-regexp-for-matching-a-tag-tiddlytweeter#post7

ext Regular Expression Quantifiers

EXT
https://www.rexegg.com/regex-quantifiers.html

ext Roman to Decimal ZIP

EXT
VBNet_Project\Examples\Roman_To_Decimal.zip

ext Shuffle List Entries

EXT
TiddlyWiki_Code\Snapshot\mklauber TWPlugin Shuffle.txt.html

ext SitePoint Exports Node.JS

EXT
https://www.sitepoint.com/understanding-module-exports-exports-node-js/

ext SO.com RunTime Net 4.5

EXT
https://stackoverflow.com/questions/8517159/how-do-i-detect-at-runtime-that-net-version-4-5-is-currently-running-your-code

ext SQLite Blob text

EXT
https://stackoverflow.com/questions/15366594/convert-hex-to-text-using-sqlite

ext SQLite DB Browser

EXT
https://sqlitebrowser.org/dl/

ext SQLite Language functions

EXT
https://sqlite.org/lang_corefunc.html

ext SQLite schema information

EXT
https://stackoverflow.com/questions/6460671/sqlite-schema-information-metadata

ext SQLite Top 5 Records

EXT
https://stackoverflow.com/questions/2728999/how-to-get-top-5-records-in-sqlite

ext StackOverflow CSS location

EXT
https://stackoverflow.com/questions/1642212/whats-the-difference-if-i-put-css-file-inside-head-or-body

ext StackOverflow Hide Parent Show Child tag

EXT
https://stackoverflow.com/questions/12956937/display-html-child-element-when-parent-element-is-displaynone

ext StackOverflow Meta UA-Compatible

EXT
https://stackoverflow.com/questions/6771258/what-does-meta-http-equiv-x-ua-compatible-content-ie-edge-do#:~:text=The%20X%2DUA%2DCompatible%20meta%20tag%20allows%20web%20authors%20to,meta%20tag%20in%20certain%20circumstances.

ext Tiddly Wiki Home Button source code

EXT
https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/PageControls/home.tid

ext TiddlyWiki Save Button source code

EXT
https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/PageControls/savewiki.tid

ext TiddlyWiki TopBar Menu

EXT
https://github.com/Jermolene/TiddlyWiki5/blob/master/core/ui/TopRightBar/menu.tid

ext TW Addon Text Replace

EXT
TiddlyWiki_Code\AddOns\Text Replace Bar.htm

ext TW Create Javascript Plugin

EXT
https://sudonull.com/post/97468-How-to-write-a-plugin-for-TiddlyWiki

ext TW Features

EXT
TiddlyWiki_Code\Features\TW Features.htm

ext TW JS Pretty

EXT
TW Project\JS_Pretty\TW JS Pretty.htm

ext TW Manual

EXT
TiddlyWiki_Code\Snapshot\TheBook - The TiddlyWiki Manual.txt.html

ext TW Return

$:/positivesigner/text-ref
\define TW_Return(ur_url, ur_link_title)
<div style="float:right"><a href="$ur_url$"> ($ur_link_title$)</a></div>
\end
<$list variable=found_index filter="[{$:/info/url/full}split[/]count[]subtract[1]]">
<$list variable=skip_html filter="[<tv-config-toolbar-icons>match[no]]">
<$list variable=return_url filter="[{$:/info/url/full}split[/]butfirst<found_index>first[]split[.html]join[.htm]addprefix[src/]]">
<$macrocall $name=TW_Return ur_url=<<return_url>> ur_link_title="TiddlyWiki view of website" />
</$list><!--found_html-->
</$list><!--skip_html-->
<$list variable=found_html filter="[<tv-config-toolbar-icons>!match[no]]">
<$list variable=return_url filter="[{$:/info/url/full}split[/]butfirst<found_index>first[]split[.html]join[.htm]split[.htm]join[.html]addprefix[../]]">
<$macrocall $name=TW_Return ur_url=<<return_url>> ur_link_title="Static HTML view of website" />
</$list>
</$list><!--found_html-->
</$list><!--found_index-->

ext TW Snapshot Review

EXT
TiddlyWiki_Code\Snapshot\Browse Code tiddlywiki_v5d01d23pre-release.htm

ext TW Snapshot v5d01d23 empty

EXT
TW Project\Snapshot\tw_empty_v5d01d23.html

ext TW Snapshot v5d01d23 main-site

EXT
TW Project\Snapshot\tiddlywiki_v5d01d23_main-site.html

ext TW Snapshot v5d01d23 pre-release

EXT
TW Project\Snapshot\tiddlywiki_v5d01d23_pre-release.html

ext TW Snapshot v5d01d23 update

EXT
TW Project\Snapshot\tiddlywiki_v5d01d23_update.html

ext Unicode Block 00-Basic Latin

EXT
https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block)

ext Unicode Block 01-Latin Supplement

EXT
https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)

ext Unicode Block Planes

EXT
https://en.wikipedia.org/wiki/Plane_(Unicode)

ext Unicode Character Database

EXT
http://www.unicode.org/Public/UCD/latest/

ext Unicode Code Block List

EXT
https://en.wikipedia.org/wiki/Unicode_block

ext VBNetScript.EXE

EXT
VBNet_Project\VBNetscript\VBNetScript_EXE.zip

ext VBNetScript.SLN

EXT
VBNet_Project\VBNetscript\VBNetScript_Project.zip

ext W3.org HTML401 Meta

EXT
https://www.w3.org/TR/html401/struct/global.html#h-7.4.4

ext W3.org HTML401 Profiles

EXT
https://www.w3.org/TR/html401/struct/global.html#profiles

ext W3Schools DocType

EXT
https://www.w3schools.com/tags/tag_doctype.asp

ext W3Schools Head tag

EXT
https://www.w3schools.com/tags/tag_head.asp

ext W3Schools Meta HTTP-EQUIV

EXT
https://www.w3schools.com/tags/att_meta_http_equiv.asp

ext W3Schools NoScript tag

EXT
https://www.w3schools.com/tags/tag_noscript.asp

ext WestWindCom Net Core Runtime

EXT
https://weblog.west-wind.com/posts/2018/Apr/12/Getting-the-NET-Core-Runtime-Version-in-a-Running-Application

ext WHATWg.org Link Icon

EXT
https://html.spec.whatwg.org/multipage/links.html#rel-icon

ext Wiki Move HTM

EXT
VBNS_Project\Wiki_Move\Wiki Move HTM.htm

ext Windows Alt-Numpad Unicode

EXT
https://conemu.github.io/en/AltNumpad.html

ext Windows Environment Variable List

EXT
https://docs.microsoft.com/en-us/windows/deployment/usmt/usmt-recognized-environment-variables#bkmk-1

ext Windows Terminal Unicode Support

EXT
https://devblogs.microsoft.com/commandline/introducing-windows-terminal/

ext WindowsCLI Unicode Support

EXT
https://www.generacodice.com/en/articolo/203149/How-to-use-unicode-characters-in-Windows-command-line

FFMPeg

DOC
<<glbl_article_list>>

FFMPeg\Extract Captions file

WindowsOS Text Extract
```
chcp 65001
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" "C:\UrPath\UrFile.srt"
pause

FFMPeg\Extract JPG files

Video Extract WindowsOS
"""
[ffmpeg.exe command-line options]
- `-ss 05:00 -t 10:00` means start at 5min and end 10min later at 15min
- `-r 1` means 1 frame per second
- `-r 0.25` means 1 frame every 4 seconds
- `-r 0.083` means 1 frame every 12 seconds, or 5 frames per minute, 50 frames out of every ten minutes, or 300 frames every hour

- IrfanView can create a portrait contact sheet with 5 columns, representing one min of video per row, 10 rows per page showing 10 minutes of video
- IrfanView can create a landscape contact sheet with 7 columns is one 3 min per 2 rows, 7 rows per page showing 10.5 minutes of video, two pages showing 21 minutes

- Open on thumbnail image with IrfanView, select File menu Thumbnails option
- Select all files in the folder, select File menu Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

"""

```
chcp 65001
rem -ss 05:00 -t 10:00 means start at 5min and end 10min later at 15min
C:\UrPath\ffmpeg.exe -i "C:\UrPath\UrFile.mp4" -r 0.083 -s 320x180 "UrPath\UrSubdir\output_%%04d.jpg"


Font Size

$:/positivesigner/text-ref
<$list variable=cur_entry filter="[all[tiddlers]!suffix[.js]!suffix[.css]!match[$:/core]!prefix[$:/config/]!prefix[$:/DefaultTiddlers]!prefix[$:/Import]!match[$:/isEncrypted]!prefix[$:/language/]!prefix[$:/theme]!prefix[$:/temp/]!prefix[$:/status/]!match[$:/StoryList]!match[$:/HistoryList]!match[$:/SiteTitle]!match[$:/SiteSubtitle]!prefix[$:/state/]count[]]">
Specific prefix filter: <<cur_entry>> cards
</$list>

<$list variable=cur_entry filter="[all[tiddlers]!is[system]] [prefix[$:/positivesigner]] +[count[]]">

Non-system plus system PositiveSigner filter: <<cur_entry>> cards
</$list>


<$button>
<$list variable=cur_card filter="[!is[system]!prefix[Draft of]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[append[COPY]]"/>
</$list>
Append COPY tag to all non-system cards
</$button><br>

<$button>
<$list variable=cur_card filter="[tag[COPY]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[remove[COPY]]"/>
</$list>
Remove COPY tag from all cards
</$button><br>


<$button>
{{keyboard action FontLarge}}
Big Font
</$button>

<$button>
{{keyboard action FontNormal}}
Normal Font
</$button>

[[Panel]]

!!Cards where has[tags] does not work

<$list variable=cur_card filter="[is[tiddler]]">
<$list variable=has_tags_test filter="[<cur_card>!has[tags]count[]] [<cur_card>has[tags]count[]] +[sum[]match[0]]">

<$link to=<<cur_card>> />
</$list><!--has_tags_test-->
</$list><!--cur_card-->

!!Cards with no tags

<$list variable=cur_card filter="[!is[system]is[tiddler]!has[tags]!prefix[Draft of]!prefix[$:/state/]!prefix[$:/library/]!prefix[$:/boot/]!prefix[$:/temp/]!match[$:/core]!match[$:/Import]!match[$:/isEncrypted]!match[$:/SiteSubtitle]!match[$:/SiteTitle]!prefix[$:/status/]!match[$:/StoryList]!match[$:/HistoryList]!match[$:/theme]!match[$:/themes/tiddlywiki/snowwhite]!match[$:/themes/tiddlywiki/vanilla]]">
<$list variable=has_parent_card filter="[<cur_card>split[\]count[]match[1]]">

<$link to=<<cur_card>> />
</$list><!--has_parent_card-->

<$list variable=has_parent_card filter="[<cur_card>split[\]count[]!match[1]]">
<$list variable=parent_card_exists filter="[<cur_card>split[\]first[]!is[tiddler]]">

<$link to=<<cur_card>> />
</$list><!--parent_card_exists-->
</$list><!--has_parent_card-->
</$list><!--cur_card-->


[[parm SkipSaveExportHTML]]

[[btn Delete Cards]]

GitCLI

DOC
<<glbl_article_list>>

GitCLI\Checkout hash

FileSystem GitCode Extract
```
@echo off
SET ur_repo=
SET ur_branch=
"C:\UrPath\git.exe" -C %ur_repo% checkout -b test-branch %ur_branch%

rem Use GitHub Desktop to delete the branch

GitHubDesktop

DOC
<<glbl_article_list>>

GitHubDesktop\Git executable

WindowsOS FileSystem GitCode
"""
When GitHub Desktop is installed, the Git.exe program is placed in the %APPDATA% folder. There is one sub-directory for each version of Git that has been downloaded. Look for the latest version-numbered folder.
"""

```
C:\Users\UrUser\AppData\Local\GitHubDesktop\app-UrVersion
```

"""
Under the app-UrVersion folder, find the Git.exe program
"""

```
app-UrVersion\resources\app\git\cmd\git.exe

GoogleContacts

DOC
<<glbl_article_list>>

GoogleContacts\Export as CSV

Service FileSystem Extract
"""
[https://contacts.google.com/]
- [Left-side menu]
- Click button Export -> Opens dialog
- Export contacts = Contacts (total count)
- Export as = Google CSV
- Click button Export -> Downloads file, Closes dialog

[CSV file]
- Header fields =
"""

```
Name
Given Name
Additional Name
Family Name
Yomi Name
Given Name Yomi
Additional Name Yomi
Family Name Yomi
Name Prefix
Name Suffix
Initials
Nickname
Short Name
Maiden Name
Birthday
Gender
Location
Billing Information
Directory Server
Mileage
Occupation
Hobby
Sensitivity
Priority
Subject
Notes
Language
Photo
Group Membership
E-mail 1 - Type
E-mail 1 - Value
E-mail 2 - Type
E-mail 2 - Value
Phone 1 - Type
Phone 1 - Value
Phone 2 - Type
Phone 2 - Value
Address 1 - Type
Address 1 - Formatted
Address 1 - Street
Address 1 - City
Address 1 - PO Box
Address 1 - Region
Address 1 - Postal Code
Address 1 - Country
Address 1 - Extended Address
Organization 1 - Type
Organization 1 - Name
Organization 1 - Yomi Name
Organization 1 - Title
Organization 1 - Department
Organization 1 - Symbol
Organization 1 - Location
Organization 1 - Job Description
Relation 1 - Type
Relation 1 - Value
Website 1 - Type
Website 1 - Value
```

- Header line =

```
Name,Given Name,Additional Name,Family Name,Yomi Name,Given Name Yomi,Additional Name Yomi,Family Name Yomi,Name Prefix,Name Suffix,Initials,Nickname,Short Name,Maiden Name,Birthday,Gender,Location,Billing Information,Directory Server,Mileage,Occupation,Hobby,Sensitivity,Priority,Subject,Notes,Language,Photo,Group Membership,E-mail 1 - Type,E-mail 1 - Value,E-mail 2 - Type,E-mail 2 - Value,Phone 1 - Type,Phone 1 - Value,Phone 2 - Type,Phone 2 - Value,Address 1 - Type,Address 1 - Formatted,Address 1 - Street,Address 1 - City,Address 1 - PO Box,Address 1 - Region,Address 1 - Postal Code,Address 1 - Country,Address 1 - Extended Address,Organization 1 - Type,Organization 1 - Name,Organization 1 - Yomi Name,Organization 1 - Title,Organization 1 - Department,Organization 1 - Symbol,Organization 1 - Location,Organization 1 - Job Description,Relation 1 - Type,Relation 1 - Value,Website 1 - Type,Website 1 - Value
```

- Sample data 1

```
.me,.me,,,,,,,,,,,,,,,,,,,,,,,,,,,Imported 8/5/16 ::: * myContacts,,,,,Mobile,5554443333 ::: 16665554444,,,,,,,,,,,,,,,,,,,,,,,
```

- Sample data 2

```
UrContactName,UrContactFirstName,,UrContactLastName,,,,,,,,,,,,,,,,,,,,,,,,,* myContacts,,,,,Mobile,(444) 333-2222,,,,,,,,,,,,,,,,,,,,,,,
```

GoogleGmail

DOC
<<glbl_article_list>>

GoogleGmail\Export as MBOX

Service Extract FileSystem
"""
[https://takeout.google.com/]
- [Products section]
- Click link Deselect All
- [Mail section]
- checkbox = set
- [End of Page section]
- Click button Next Step -> Navigates section
- [Choose file type, frequency & destination]
- Frequency = Export once
- File type = .zip
- File size = 2 GB
- Click button Create Export -> Navigates section
- [Export Progress]
- Note: Google is creating a copy of files from Mail. This process can take a long time (possibly hours or days) to complete. You'll receive an email when your export is done.

[https://mail.google.com/]
- [Message with title "Archive of Google data requested"]
- Note: You can ignore the message or click the link to verify it was you
- [Message with title "Your Google data is ready to download"]
- Click button Download Your Files -> Opens tab

[Google Takeout form]
- Re-enter your password
- [Record where Export = Mail]
- Note: The size of the export file is also in the Export column
- Click button Download -> Downloads file
- Note: The file may take a long time to download depending on your internet connection and the size of the file

[ZIP file]
- Extract the ZIP file to a folder

[Takeout folder]
- Open the archive_browser.html -> Opens browser

[Archive Browser page]
- [File Formats tab]
- Note: An mbox is a way of storing mail messages and is supported by common mail clients like Microsoft Outlook, Mozilla Thunderbird, and Apple's Mail program. These files are most easily opened by a dedicated mail client like those listed above

[Takeout\Mail folder]
- [All mail Including Spam and Trash.mbox]
- Use Mozilla Thunderbird to read the MBOX file
- OR Split this file into smaller text files... [[somehow |VBNetCode\Copy File Lines]]
- Format:

Record Start = Leading "From " <- Including the space
Tags = "WordsWithoutSpaces:" <- no spaces in tag name
Tag continuation values = " Every Line With Leading Space Or Tab After Tag Name"
Email Content = "First line that is not a tag or tag continuation -> through last line before next leading " "From "

GoogleGmail\MBOX file parsing test

Service Extract Text
```
start "" "%~dp0\MxClasses\VBNetScript.exe" /path=%0 & exit
MxClasses\MxBaseEc12.vb
RetVal = Mx.Want.TextFile_Split_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.TextFile_Split_errhnd
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub TextFile_Split(ret_message As Strap)
			Dim tabchr = CHR(9)
			Dim flnDATA = FileNamed().d("C:\Users\Dad\Downloads\Takeout\Mail\All mail Including Spam and Trash.mbox")
			Dim intLINE_COUNT = 0
			Dim sdaPREFIX_SKIPPED = New Sdata
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), False, gUTF8_FileEncoding)
				Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
				    Dim bolINCLUDE_INDENTED_LINES = False
					Dim bolHTML_TEXT = False
					Dim bolPLAIN_TEXT = False
					Dim bolSKIP_TEXT = False
					While stmDATA.EndOfStream = False
						Dim strLINE = stmDATA.ReadLine()
						If strLINE.Length = 0 Then
						
						ElseIf Left(strLINE, 5) = "From " AndAlso
						  Len(strLINE) = 59 Then
						    bolINCLUDE_INDENTED_LINES = False
							bolHTML_TEXT = False
							bolPLAIN_TEXT = False
							bolSKIP_TEXT = False
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine()
							stmOUT_FILE.WriteLine(strLINE)
							intLINE_COUNT += 1
						
						ElseIf bolSKIP_TEXT Then
						
						ElseIf bolPLAIN_TEXT Then
							If strLINE.Trim.Length > 0 Then
								Dim bolCUR_HTML = False
								Dim intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									bolCUR_HTML = True
									
									End If
								
								If Left(strLINE, 16) = "X-Attachment-Id:" OrElse
								  Left(strLINE, 32) = "Content-Transfer-Encoding:base64" Then
									bolSKIP_TEXT = True
									
									End If 'strLINE
								
								If bolHTML_TEXT = False Then
									stmOUT_FILE.WriteLine(strLINE)
									intLINE_COUNT += 1
								
								ElseIf bolCUR_HTML Then
									Dim strTEXT = strLINE
									While intFOUND_SPRTR > 0
										Dim strPREFIX = Mid(strTEXT, 1, intFOUND_SPRTR - 1)
										Dim strTAG = Mid(strTEXT, intFOUND_SPRTR)
										intFOUND_SPRTR = InStr(strTAG, ">")
										If intFOUND_SPRTR = 0 Then
											strTEXT = strPREFIX
										
										Else
											strTEXT = strPREFIX & Mid(strTAG, intFOUND_SPRTR + 1)
											intFOUND_SPRTR = InStr(strTEXT, "<")
											
											End If 'intFOUND_SPRTR
										
										End While 'intFOUND_SPRTR
									
									If strTEXT.Trim.Length > 0 Then
										stmOUT_FILE.WriteLine(strTEXT)
										intLINE_COUNT += 1
										
										End If
									
									End If 'intFOUND_SPRTR
									
								End If 'strLINE
							
						ElseIf (Left(strLINE, 1) = s OrElse Left(strLINE, 1) = tabchr) AndAlso
						  bolINCLUDE_INDENTED_LINES Then
							'stmOUT_FILE.WriteLine(strLINE)
							'intLINE_COUNT += 1
						    
						Else 'strLINE
						    bolINCLUDE_INDENTED_LINES = False
							Dim strPREFIX = mt
						    Dim intFOUND_SPRTR = InStr(strLINE, ":")
							If intFOUND_SPRTR > 0 Then
							    strPREFIX = Mid(strLINE, 1, intFOUND_SPRTR)
								If InStr(strPREFIX, tabchr) > 0 OrElse
								  InStr(strPREFIX, s) > 0 Then
									strPREFIX = mt
									
									End If
								
								End If
							
							If strPREFIX = "Content-Type:" OrElse
							  strPREFIX = "Subject:" OrElse
							  strPREFIX = "To:" OrElse
							  strPREFIX = "Date:" OrElse
							  strPREFIX = "From:" Then
								bolINCLUDE_INDENTED_LINES = True
								stmOUT_FILE.WriteLine(strLINE)
								intLINE_COUNT += 1
							
							ElseIf Right(strPREFIX, 1) = ":" Then
								bolINCLUDE_INDENTED_LINES = True
								If sdaPREFIX_SKIPPED.Contains(strPREFIX) = False Then
									sdaPREFIX_SKIPPED.d(strPREFIX)
									
								    End If
							
							ElseIf strPREFIX = "" Then
							    bolPLAIN_TEXT = True
								intFOUND_SPRTR = InStr(strLINE, "<")
								Dim intFOUND_TAGCLOSE = InStr(strLINE, ">")
								If intFOUND_SPRTR > 0 AndAlso
								  intFOUND_TAGCLOSE > intFOUND_SPRTR Then
									bolHTML_TEXT = True
									
									End If
								
								End If 'strPREFIX
							
							End If 'strLINE
						
						If intLINE_COUNT >= 100000 Then
							Exit While
							
							End If
						
						End While 'stmDATA
					
					End Using 'stmDATA
				
				End Using 'stmOUT_FILE
			
			Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("PREFIX_SKIPPED.TXT"), False, gUTF8_FileEncoding)
				Call sdaPREFIX_SKIPPED.Sort()
				For Each strENTRY In sdaPREFIX_SKIPPED
					stmOUT_FILE.WriteLine(strENTRY)
					
					Next strENTRY
				
				End Using 'stmOUT_FILE

			ret_message.Clear.d(intLINE_COUNT.ToString)
			
			End Sub 'TextFile_Split

        Public Shared Function TextFile_Split_errhnd() As Strap
            Dim stpRET = Strapd()
            TextFile_Split_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call TextFile_Split(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'TextFile_Split_errhnd
    End Class 'Want
End Namespace 'Mx

GooglePlay

DOC
<<glbl_article_list>>

GooglePlay\Share purchased apps with another account

Service FileSystem UserAction
"""
[Play Store app]
- [Top-left icon]
- Click the three-lines menu, option `Family Library` -> Navigates page
- Note: There are two Sections
- - `Added by [Other]`
- - `Added by you`

If the purchased app you want to share is not shown under the `Added by You` section, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option `My apps & games` -> Navigates page
- [Installed tab, or Library tab]
- Choose an app you purchased -> Navigates page
- [App page]
- Note: The checkbox Family Library is a toggle switch
- checkbox Family Library = set -> The app is available to all `Family` logins

If the 'Family' logins does not contain the account you want to access your shared app, you can add it.

[Play Store]
- [Top-left icon]
- Click the three-lines menu, option `Account` -> Navigates page
- [Family tab]
- Click button Manage family members -> Opens dialog
- [Family dialog]
- Click button Invite family members -> Opens dialog
- [Verify CVC dialog]
- Enter your credit card number's CVC number
- Click button Verify -> Closes dialog, Opens dialog
- [Send Invitations dialog]
- Select a contact
- Click button Send

[Added Account email]
- Click the invitation link -> Navigates page
- Note: The Added Account can now use the Play Store app to install the Family Library shared app

GooglePlusCodes

DOC
<<glbl_article_list>>

GooglePlusCodes\Find a Plus Code

Service FileSystem Extract Numbers
"""
[https://plus.codes/map/]
- [Search box, Left-side icon]
- Click the three-lines menu, option Satellite -> Refreshes window
- Click the three-lines menu, option Grid -> Refreshes window
- [Navigate to location]
- When the mouse icon is a hand, double-click to Zoom in
- Each time you click, the location will show as 8 characters, a plus sign, and two suffix characters
- - Example: 73F6C9JH+HR
- The last two Zoom levels allow you to select a single Plus Code rectangle, which has three suffix characters after the plus sign
- - Example: 73F6C9JH+HR7
- Copy the browser address bar
- - Example: https://plus.codes/73F6C9JH+HR7

- Note: You can email the page link to someone
- - They will have to turn on the satellite and / or grid options again

- Note: You can use the browser to bookmark the current page
- - Android O/S Chrome can create a desktop shortcut to the current website page (when not in Incognito mode)

- Note: The plus codes are 8 characters, a plus, and two or three suffix characters
- - The bottom of the Plus.Codes website's map only temporarily shows the three suffix characters after you click, quickly reverting to show only two suffix characters
- - You can still see all three suffix characters in the address bar

- [Bottom location code bar, Right-side icon]
- Click button Navigate (looks like a Right-Turn Only road sign) -> Navigates to Google Maps website
- Note: Android O/S Chrome app will ask to Stay On Web or Use The App
- - Click button Use The App to open the Google Maps app

HTML CSS

DOC
<<glbl_article_list>>

HTML CSS\Comment Declaration

HTMLCode Text
!! HTML 5 document

* Declaration Name = `--`
* Content = unprocessed text, except for the character sequence double-hyphen close-tag ( `-->` )
* Note: HTML declarations are not tags, because the have an exclamation mark ( `!` ) before the declaration name / code
* Note: XML documents have a requirement that a double-hyphen ( `--` ) must itself be doubled ( `----` ) when used in a comment declaration, but HTML 5 has no such requirement


!! Sample code for HTML 5 Comment

```
<!-- a text editor can see the comment text -->
```


HTML CSS\Comment MOTW Declaration

HTMLCode Text Browser
!! HTML document viewed in Internet Explorer

* Comment text sequence:

<<<
* `<!--` and optional whitespace
* `saved from url=(`
* the number of characters in the URL string (including the trailing backslash)
* `)`
* the URL string
* optional whitespace and `-->`
<<<

* HTML documents viewed in Internet Explorer show a warning message due to active content, or has a specifically crafted HTML Comment Declaration that names the root URL of the website it is being hosted on
* Note: If this is for a new site, or if the domain is not known, you can use `about:internet` as a valid URL

<<ext "JTFAssociates MOTW">>

!!Sample code

```
<!-- saved from url=(0014)about:internet -->
```

HTML CSS\Compatibility Meta tags

HTMLCode Browser Formatting
!! Declare compatibility version of Microsoft Internet Explorer web browser

* tag name = `meta`
* `http-equiv` attr = `X-UA-Compatible`
* `content` attr = `IE=Edge` or (`IE=11`, `IE=EmulateIE11`, and similar version number pairs)
* Note: Use this tag if you need features specific to an older version of IE like IE9 or IE8
* Note: If you only support the latest browsers (IE11 and/or Edge) then this tag will not affect the web page's behavior until another version is created

<<<
Internet Explorer begins interpreting markup using the latest version. When Internet Explorer encounters the X-UA-Compatible META tag it starts over using the designated version's engine. This is a performance hit because the browser must stop and restart analyzing the content.
<<<

<<ext "StackOverflow Meta UA-Compatible">>

!! Sample code

```
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
```

<<<
`content="IE=Edge" ` mode tells Internet Explorer to display content in the highest mode available. With Internet Explorer 9, this is equivalent to IE9 mode. If a future release of Internet Explorer supported a higher compatibility mode, pages set to edge mode would appear in the highest mode supported by that version. Those same pages would still appear in IE9 mode when viewed with Internet Explorer 9.
<<<

!! Specify web application runs in full-screen mode on Apple devices

* tag name = `meta`
* `name` attr = `apple-mobile-web-app-capable`
* `content` attr = `yes`
* Note: The default behavior is to use Safari to display web content
* Note: You can determine whether a webpage is displayed in full-screen mode using the window.navigator.standalone Boolean JavaScript property

<<ext "Apple.com Safari Meta tags">>

!! Sample code

<<<
<meta name="apple-mobile-web-app-capable" content="yes" />
<<<

!! Specify the Full Screen's status bar style on Apple devices

* tag name = `meta`
* `name` attr = `apple-mobile-web-app-status-bar-style`
* `content` attr = `default`, `black`, `black-translucent`
* Note: If set to black-translucent, the web content is displayed on the entire screen, partially obscured by the status bar
* Note: This meta tag has no effect unless you first specify full-screen mode as described in apple-apple-mobile-web-app-capable

<<ext "Apple.com Safari Meta tags">>

!! Sample code

```
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
```

!! Leave original formatting of telephone-number formatted strings 

* tag name = `meta`
* `name` attr = `format-detection`
* `content` attr = `telephone=no`
* Note: By default, Safari on iOS detects any string formatted like a phone number and makes it a link that calls the number

<<ext "Apple.com Safari Meta tags">>

!! Sample code

```
<meta name="format-detection" content="telephone=no" />
```

!! Specify web application runs in full-screen mode on Apple devices

* tag name = `meta`
* `name` attr = `mobile-web-app-capable`
* content = `yes`
* Note: This tells the browser to launch the page fullscreen when the user has added it to the home screen
* Note: A better option is to use the Web App Manifest for Chrome, Opera, Firefox, and Samsung browsers

<<ext "GoogleDevelopers FullScreen web app">>

!! Sample code

```
<meta name="mobile-web-app-capable" content="yes"/>
```

HTML CSS\CSS Style definitions

CSSCode Browser FileSystem
!! Place a CSS style-sheet in the HTML document

* tag name = `style`
* `type` attr = `text/css`
* Note: The most recent versions of the HTML spec now permits the &lt;style> tag within body elements
* Note: Putting CSS in body means it is loaded later and the browser starts drawing the interface faster
* Note: Putting CSS in body can decrease page performance due to possible reflows/repaints once the browser hits styles further down in the page tree

<<ext "StackOverflow CSS location">>

!! Sample code

```
<style type="text/css">
```

!! Place a comment inside of a CSS style-sheet

* Start CSS comment text with forward-slash asterisk ( `/*` )
* End CSS comment text with asterisk forward-slash ( `*/` )

<<ext "MozillaDeveloper CSS Comment">>

!! Sample code

```
<style type="text/css">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>
```

HTML CSS\Declare document Content type

HTMLCode Browser Text

HTML CSS\DocType Declaration

EXT
!! HTML 5 document

* Declaration Name = `DOCTYPE`
* Content = `html`
* Note: HTML declarations are not tags, because the have an exclamation mark ( `!` ) before the declaration name / code
* Note: This should be the first non-whitespace characters in the document to be compliant with HTML standards
* Note: HTML5 documents don't really need a DOCTYPE as there is no HTML5 DTD for browsers to refer to, but it is used in HTML5 to make sure the browser doesn’t switch into “quirks” mode and remains in full standards mode

<<ext "W3Schools DocType">>

<<ext "HTML.com DocType">>

<<ext "CodeAcademy DocType">>

!! Sample code for HTML 5 declaration

```
<!DOCTYPE html>
```


HTML CSS\Head section

HTMLCode Browser Formatting
!! Set metadata values for interpreting document contents
* The &lt;head> element is a container for metadata (data about data) and is placed between the &lt;html> tag and the &lt;body> tag
* Metadata describes how to interpret and format the HTML document stored within the &lt;body> tag

<<ext "W3Schools Head tag">>

!! Sample code

```
<head>
  <title>UrTitle</title>
</head>
```

HTML CSS\Hide content

HTMLCode Browser Formatting
!! Hide content until user action

* CSS style name = `display`
* value = `none`
* Note: The entire tag and sub-tag structure is hidden
* Note: To hide the root tag and show a child tag, use CSS styles `visibility: hidden` and `visibility: visible`, though the parent markup will still take up screen real estate

<<ext "StackOverflow Hide Parent Show Child tag">>

HTML CSS\HTTP-EQUIV Document Type

HTMLCode Browser FileSystem
!! Simulate an HTTP Respsonse header

* The http-equiv attribute value `content-type` provides an HTTP header specifying that the character encoding for the document is in the content attribute

<<ext "W3Schools Meta HTTP-EQUIV">>

!! Sample code

```
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
```

HTML CSS\iFrame to Local HTML file

HTMLCode FileSystem Extract
```
<iframe src="UrPath\UrFile.html" scrolling=yes style="border-style:none;height:75%;width:100%" ></iframe>

HTML CSS\Language attribute on tags

HTMLCode Browser Formatting
!! Allow screen-reader to identify the page's default language and / or accent

* tag name = any
* `lang` attr = an ISO-639 Language code
* The official W3C recommendation is to declare the primary language for each Web page with a &lt;...lang => attribute in the &lt;html> tag
* Note: The LANG tag (i.e. the lang="" attribute) is designed to signal screen readers pronunciation engines to switch to another language or accent

<<ext "PSU.edu LangTag">>

!! Sample code

```
<html lang="en-GB">
```

HTML CSS\META Tag names

Browser HTMLCode AssignVariable
!! Identify tool or program used to create the website

* tag name = `META`
* `name` attr = `generator`
* `content` attr = The name of the program you used to create your website
* Note: This tag is automatically inserted by website-generating applications
* Note :People who don’t want to advertise which tool or program they used to create the website can remove this tag from the generated pages

<<ext "MetaTags.org Generator">>

!! Sample code

```
<meta name="generator" content="UrProgramTitle" />
```

!! Identifies the name of the application running in the web page

* tag name = `META`
* name attr = `application-name`
* `content` attr = The application that is dynamically supplying content for the current web page
* Note: isolated web pages shouldn't define an application-name

<<ext "Mozilla.org META tags">>

```
<meta name="application-name" content="UrApplicationTitle" />
```

!! Supply hints about the size of the initial size of the viewport

* tag name = `META`
* `name` attr = viewport'
* `content` attr = comma-separated list of equates
* Note: This is used by mobile devices only
* Note: The default values may vary between devices and browsers
* Note: Disabling zooming capabilities by setting user-scalable to a value of no prevents people experiencing low vision conditions from being able to read and understand page content

<<<
* width = ( A positive integer number ) or ( the text `device-width` )
* height = ( A positive integer) or ( the text `device-height` )
* initial-scale = A positive number between 0.0 and 10.0
* maximum-scale = A positive number between 0.0 and 10.0
* minimum-scale = A positive number between 0.0 and 10.0
* user-scalable = `yes`, `no`
* viewport-fit = `auto', 'contain`, `cover`
<<<

<<ext "Mozilla.org META tags">>

!! Sample code

```
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
```

!! Include developer or company information in document

* tag name = `meta`
* `name` attr = `copyright`, `ur_app_name-version`
* `content` attr = Any text data
* Note: This information is not used by the browser

HTML CSS\Meta Tag Schema

HTMLCode AssignVariable Browser
<<ext "W3.org HTML401 Meta">>

This specification does not define a set of legal meta data properties.
The meaning of a property and the set of legal values for that property should be defined in a reference lexicon called a profile.

<<ext "W3.org HTML401 Profiles">>

The profile attribute of the HEAD specifies the location of a meta data profile.
The value of the profile attribute is a URI.
User agents may use this URI in two ways:

* As a globally unique name.

<<<
User agents may be able to recognize the name (without actually retrieving the profile) and perform some activity based on known conventions for that profile.
For instance, search engines could provide an interface for searching through catalogs of HTML documents, where these documents all use the same profile for representing catalog entries.
<<<

* As a link.

<<<
User agents may dereference the URI and perform some activity based on the actual definitions within the profile (e.g., authorize the usage of the profile within the current HTML document).
This specification does not define formats for profiles.
<<<


HTML CSS\Noscript alternate content

EXT
!! Add content when viewed with JavaScript-disabled browsers

* tag name = `noscript`
* Note: The tag contents are displayed to users that have disabled scripts in their browser or have a browser that doesn't support user action event scripting

<<ext "W3Schools NoScript tag">>

!! Sample code

```
</noscript>
<!--Javascript-disabled browser additional content-->
</noscript>
<!--Ordinary content-->
```

HTML CSS\Padding and Margin

HTMLCode CSSCode Formatting
```
style="margin-left:30px"

style="padding-left:10px"

HTML CSS\Table Rows Alternate

HTMLCode Formatting CSSCode
Stylesheet classes:

```
.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}
```

HTML using class

```
<table class="alternating-rows">
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

HTML CSS\Website icon

HTMLCode Browser Formatting FileSystem
!! Show an icon next to the Website Name

* tag name = `link`
* `rel` attr = `icon`, `shortcut icon`
* `href` attr = Website icon filename, relative path, or full path
* Note: The favicon is loaded as soon as the browsers parses the link rel="icon" declaration, or after the page is loaded when the link is not found
* Note: The icon keyword may be preceded by the keyword "shortcut". If the "shortcut" keyword is present, the rel attribute's entire value must be an ASCII case-insensitive match for the string "shortcut icon" (with a single U+0020 SPACE character between the tokens and no other ASCII whitespace).

<<ext "MathiasBynens Rel Icon">>

<<ext "WHATWg.org Link Icon">>

!! Sample code

```
<link rel="shortcut icon" href="favicon.ico">
```

Instapaper

DOC
<<glbl_article_list>>

Instapaper\Export as CSV

Extract FileSystem Service
"""
[https://www.instapaper.com/u]
- [Top-right icon]
- Click login-name menu, option Settings -> Navigates page
- [Settings page, Export section]
- Click link Download .CSV file -> Opens dialog
- Click button OK -> Starts download, closes dialog

[CSV file]
- Header fields =
"""

```
URL
Title
Selection
Folder
Timestamp
```

- Header line =

```
URL,Title,Selection,Folder,Timestamp
```

- Sample data 1 =

```
https://m.youtube.com/watch?v=ABC123DEF&index=14,"""UrQuotedText"" - UrVideoTitle",UrCommentText,"UrInstapaperFolder",1605840648
```

- Sample data 1 =

```
https://www.urcompany.com/urfolder/urarticle/,UrArticleTitle,,UrInstapaperFolder,UrCommentText1603883475
```

Instapaper\Parse file

Text Extract Service
```
\define link_title()
''[<$list filter="[<http_text>split[,]butlast[]last[]]" />]'' <$list filter="[<http_text>split[,]rest[]first[]]" />
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]floor[]]"><$vars tid_year=<<currentTiddler>> >
<$list filter="[<http_text>split[,]last[]divide[60]divide[60]divide[24]divide[365]add[1970]subtract<tid_year>multiply[12]floor[]]"><$vars tid_month=<<currentTiddler>> >
(<<tid_year>>-<<tid_month>>)
</$vars></$list>
</$vars></$list>
<ul>
<$list filter='[<http_text>split[,]butlast[]butlast[]butfirst[]butfirst[]join[,]split["]butfirst[]butlast[]join["]split[""]join["]split[...]]'>
<li><<currentTiddler>></li>
</$list>
</ul>
\end
<$list filter="[{WebNotes\Data}split[http]count[]]" ><$vars total_count=<<currentTiddler>> >Count of entries: <<total_count>><br><br>
<!--
<$button>
<$action-setfield $tiddler="$:/state/popup/audit_1k" text="0"/>
Reset
</$button><br>

<$button>
<$list filter="[{$:/state/popup/audit_1k}add[1000]]">
<$action-setfield $tiddler="$:/state/popup/audit_1k" text=<<currentTiddler>> />
Next 1k
</$list>
</$button><br>
{{$:/state/popup/audit_1k}}

<$list filter="[{WebNotes\Data}split[http]first{$:/state/popup/audit_1k}last[1000]]"><$vars http_text=<<currentTiddler>> >
-->
<$list filter="[{WebNotes\Data}split[{{]join[-opencurlybrace-]split[http]]"><$vars http_text=<<currentTiddler>> >
<$list filter="[<http_text>split[,]first[]!suffix[URL]addprefix[http]]"><$vars http_link=<<currentTiddler>> >
<$list filter="[all[tiddlers]field:twnote<currentTiddler>count[]match[0]]">
<<http_link>><br>
- <<link_title>> <br>
</$list>
</$vars></$list>
</$vars></$list>
</$vars></$list>
```

IrfanView

DOC
<<glbl_article_list>>

IrfanView\Contact Sheet

WindowsOS Formatting Video
"""
[IrfanView app]
- Open one thumbnail image -> Loads image
- Click the File menu option Thumbnails -> Opens dialog
- [Thumbnails dialog]
- Select all files in the folder
- Click the File menu, option Create Contact Sheet
- 1280x738, 738/1280*320 = 184.5, use -s 320x180 to keep aspect ratio
- paper 150px * 8.5in = 1250px wide, 150px * 11in = 1650in tall
- screen 1920px x 1080px with 7 x 7, stretch small images to maximal size

JavaScript

DOC
<<glbl_article_list>>

JavaScript\Comment text

CSSCode Browser FileSystem
!! Place a comment text block inside of a JavaScript program

* tag name = `script`
* `type` attr = `text/javascript`
* Start JavaScript comment text block with forward-slash asterisk ( `/*` )
* End comment text with asterisk forward-slash ( `*/` )
* Start JavaScript comment text line with two forward-slashes ( `//` )

!! Sample code

```
<style type="text/javascript">/*
Comment text
*/

.ur_class_name {
  width: 50%;
}
</style>
```

JavaScript\Execute Nameless Function

JavaScriptCode FileSystem UserAction
```
;(
    function() {
        alert('hi');
        }
    )();

JavaScript\Exports object

JavaScriptCode FileSystem
!! Determine if running under Node.JS

* Initially at least, `exports` is a reference to `module.exports`
* If you assign anything to `module.exports`, `exports` is not no longer a reference to it, and exports loses all its power

<<ext "SitePoint Exports Node.JS">>

JavaScript\Invalid Variable Names

JavaScriptCode ErrorHandling AssignVariable
<<ext "JavaScript Strict Mode">>

Strict mode makes assignments which would otherwise silently fail to throw an exception.  For example, NaN is a non-writable global variable. In normal code assigning to NaN does nothing; the developer receives no failure feedback. In strict mode assigning to NaN throws an exception.

```
'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError
```

Strict mode in ECMAScript 2015 forbids setting properties on primitive values. Without strict mode, setting properties is simply ignored (no-op), with strict mode, however, a TypeError is thrown.

```
(function() {
'use strict';

false.true = '';         // TypeError
(14).sailing = 'home';   // TypeError
'with'.you = 'far away'; // TypeError

})();
```

JavaScript\Labels

JavaScriptCode FileSystem CodeLibrary
The labeled statement can be used with break or continue statements.

```
List: 
while(counter < 50)
{
     userInput += userInput;
     counter++;
     if(userInput > 10000)
     {
          break List;
     }
}
```

```
var i = 100, j = 100;
outerloop:
while(i>0) {
  while(j>0) {
   j++

   if(j>50) {
     break outerloop;
   }
  }
i++

}
```

```
loop1:
for (let i = 0; i < 5; i++) {
  if (i === 1) {
    continue loop1;
  }
  str = str + i;
}
```

JavaScript\Logical And/Or

JavaScriptCode Numbers
If a value can be converted to true, the value is so-called truthy. If a value can be converted to false, the value is so-called falsy.

Examples of expressions that can be converted to false are:

* null
* NaN
* 0
* empty string ( ` "" ` or ` '' ` ) or empty template literal ( &#x0060;&#x0060; )
* undefined

The logical OR expression is evaluated left to right, and first truthy returned expression stops evaluation of the remaining expressions

The && operator is executed before the || operator

Note: If you use this operator to provide a default value to some variable, be aware that any falsy value will not be used. If you only need to filter out null or undefined, consider using the nullish coalescing operator ( ` ?? ` )

JavaScript\Multi-line string

JavaScriptCode Text Formatting
It's not a multiline string, it's a one line string split over multiple lines of code that make up a single statement.

Old version uses backslash as a line continuation character:

```
eval(" \
alert('hi'); \
");
```

New version uses backtick character as multi-line string:

WARNING: Not supported by IE

```
eval(`
alert('hi');
`);
```

Use string concatenation instead:

```
eval(
"var v1 = 'hi';" +
"alert(v1);"
);
```


JavaScript\Run in HTML Document

JavaScriptCode HTMLCode UserAction
```
<html>
  <body><script type = "text/javascript">window.onerror=function(msg,url,line){alert("Line number = "+line+"\nMessage:\n\n"+msg)}</script>
    <script type="text/javascript">
alert('hi';
      </script>
    </body>
  </html>

JavaScript\Strict Mode

JavaScriptCode CodeLibrary Text
!! Show strict mode compilation errors on specific scripts or functions

* First statement in script or function: 'use strict'; or "use strict";
* Note: Strict mode applies to entire scripts or to individual functions, not individual block statements enclosed in {} braces within a function
* Note: Strict mode code and non-strict mode code can coexist, so scripts can opt into strict mode incrementally
* Note: The entire contents of JavaScript modules are automatically in strict mode, with no statement needed to initiate it

<<ext "MozillaDeveloper Strict mode">>

!! Sample data

```
"use strict";
mistypeVariable = 17;
```

<<<
Result in Developer Tools, Javascript Console:

```
Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLineNumber
```
<<<

```
<script type="module">
mistypeVariable = 17;
</script>
```

<<<
Result:

```
Uncaught ReferenceError: mistypeVariable is not defined
    at UrFile.html:UrLine
```
<<<

JavaScript\String Escape Codes

JavaScriptCode Text CodeLibrary
"""
Here are all the string escape codes:

\0 The NUL character (\u0000)
\b Backspace (\u0008)
\t Horizontal tab (\u0009)
\n Newline (\u000A)
\v Vertical tab (\u000B)
\f Form feed (\u000C)
\r Carriage return (\u000D)
\" Double quote (\u0022)
\' Apostrophe or single quote (\u0027)
\\ Backslash (\u005C)
\x XX The Latin-1 character specified by the two hexadecimal digits XX
\u XXXX The Unicode character specified by the four hexadecimal digits XXXX

JavaScript\This object

JavaScriptCode CodeLibrary
<<ext "JavaScript This Parameter">>

Functions called via property references get "this" set for them: This is the part that really makes it seem like JavaScript has methods: The "this" reference gets set automagically to the object instance if you call a function via a property reference.

Within that call, use the object in question as "this". Getting the function reference from an object property doesn't link it in any way to the object the property came from. The JavaScript engine treats calls of functions just retrieved from object properties as special and sets up "this" accordingly. Essentially, "this" is just a function argument that's passed into the function as an implicit feature of calling a function via a property reference.

JavaScript gives us the call and apply methods on function instances, with which we can say explicitly what we want "this" to be. If you say myfunction.call(myobject), you're saying "call myfunction and use myobject as 'this'", which is what the property-retrieval stuff does implicitly for you.

`UrObject.UrFunction();`

- equates to -

`UrObject.UrFunction.call(UrObject);`

Everything can be seen as a function.

`window['UrObject']['UrFunction'].call(window['UrObject']);`

Getting the function reference from the property (UrObject.UrFunction) is distinct from the fact we're calling it (call) is distinct from what "this" should be ((UrObject)).

<<ext "JavaScript Closures">>

The interpreter creates a call object for this particular execution of the function and sets some properties on that call object before passing it into the function's code.

* A property called arguments which is an array (of sorts, in most implementations it's not actually an Array object) of the actual arguments we called the function with, plus a callee property which is a reference to the function being called.
* A property for each of the arguments defined by the function declaration. The values of these properties are set to the values passed into the function. If any arguments weren't specified (because JavaScript lets you call functions with however many arguments you want, regardless of the definition), properties for any missing arguments are still created on the call object — with the value undefined.
* A property for every declared variable within the function (e.g., every "var" statement). (These start out with the value undefined.)

```
window.UrFunction(UrObject1, UrObject2);
```

That creates a call object for this execution of updateDisplay that essentially looks like this:

```
call.arguments = [UrObject1, UrObject2]
call.arguments.callee = UrFunction
call.ur_input_parm1 = UrObject1
call.ur_input_parm2 = UrObject2
call.internal_var1 = undefined
```

The use of the call object is implicit, because once the call object is created, it's put at the top of the scope chain for the duration of the function call.

JavaScript\TypeOf Name

JavaScriptCode CodeLibrary Text
!! Get string representing object type

* typeof always returns a string
* Note: typeof operator takes precedence over string concatenation ( ` + ` )
* Note: type a let or const variable in a block before they are declared will throw a ReferenceError

* Undefined, undeclared variable, or unassigned variable = "undefined"
* Boolean(1), !!(1) = "boolean"
* Number('321') , Infinity, NaN = "number"
* Bigint, 321n = "bigint"
* String = "string"
* Symbol = "symbol"
* Function() {}, class UrClassName {},  = "function"
* null, object, {ur_prop_name: ur_prop_value}, [ur_val1, ur_val2, ur_val3], new Date(), /regex/ = "object"

JavaScriptBookmarklets

DOC
<<glbl_article_list>>

JavaScriptBookmarklets\Bibliographic citation

<<ext "ALAorg Citations bookmarklet">>
```
javascript:(function(){var h=document.createElement('div');var t=document.getElementsByTagName('title')[0];var info='<p><strong>Title('+t.innerHTML.length+'):</strong> '+t.innerHTML+'</p>';var m=document.getElementsByTagName('meta');for(var i=0;i < m.length;i++){if(null !==m[i].getAttribute('name')){var c=m[i].getAttribute('content');info+='<p><strong>'+m[i].getAttribute('name')+'('+c.length+'):</strong> '+c+'</p>';}}var lm=document.lastModified;var url=location.href;var d=new Date();var dd=d.getDate();var mm=d.getMonth()+1;var yyyy=d.getFullYear();info+='<p><strong>Citation: </strong>"' + t.innerHTML + '." Last modified '+lm+'. <a target="_blank" href="'+url+'">'+url+'</a> (accessed '+mm+'/'+dd+'/'+yyyy+').</p>';document.body.insertBefore(h,document.body.firstChild);h.innerHTML='<div style="border:1px solid %23888;border-radius:5px;-moz-box-shadow:0 0 5px %23888;-webkit-box-shadow:0 0 5px%23888;box-shadow:0 0 5px %23888;background:%23eee;text-align:left;padding:1em;"><a href="%23" onclick="document.body.removeChild(document.body.firstChild);return false">remove</a>'+info+'</div>';})();

JavaScriptBookmarklets\Clear all CSS

Clears all the CSS Class and Style attributes

```
avascript:(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["module"], factory);
  } else if (typeof exports !== "undefined") {
    factory(module);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod);
    global.clearAllCSS = mod.exports;
  }
})(this, function (module) {
  "use strict";

  var each = Array.prototype.forEach;


  function clearAllCSS(nest_level, cur_elt) {
    var _context2;
    if (!cur_elt) {
        throw new Error("No element specified.");
        }

    var _context;
    (_context = cur_elt.children, each).call(_context, function (child) {
        clearAllCSS(nest_level+1, child);
        });

    while(cur_elt.attributes.length > 0) {
        cur_elt.removeAttribute(cur_elt.attributes[0].name);
        }
    }

  module.exports = clearAllCSS;
});
document.querySelectorAll('iframe,script,noscript').forEach(function(element){if (element!=null){element.parentNode.removeChild(element)}});
clearAllCSS(1, document.body);
if (document.head!=null){document.head.parentNode.removeChild(document.head)};
document.querySelectorAll('link').forEach(function(element){if (element!=null){element.parentNode.removeChild(element)}});
document.body.style.fontSize=prompt("Please enter font multiplier", "2") + "00%";
undefined;

JavaScriptBookmarklets\Convert to Inline CSS

Run this script (it takes a while) and then save the web page. All the CSS properties are specified on each element, so it does not need to load any stylesheets.

<<ext "GitHub LukeHorvat Computed Style to Inline">>

```
avascript:(function (global, factory) {
  if (typeof define === "function" && define.amd) {
    define(["module"], factory);
  } else if (typeof exports !== "undefined") {
    factory(module);
  } else {
    var mod = {
      exports: {}
    };
    factory(mod);
    global.computedStyleToInlineStyle = mod.exports;
  }
})(this, function (module) {
  "use strict";

  var each = Array.prototype.forEach;


  function computedStyleToInlineStyle(nest_level, parent_style, cur_elt) {
    var _context2;
    if (!cur_elt) {
        throw new Error("No element specified.");
        }

    var cur_style = getComputedStyle(cur_elt);
    var _context;
    (_context = cur_elt.children, each).call(_context, function (child) {
        computedStyleToInlineStyle(nest_level+1, cur_style, child);
        });

    var parent_copy = document.createElement("an_unknown_tag");
    if (nest_level > 1) {
        for (var pctr = 0; pctr < parent_style.length; pctr++) {
            var pname = parent_style[pctr];
            var pval = parent_style.getPropertyValue(pname);
            parent_copy.style[pname] = pval;
            }
        }

    var blank_element = document.createElement("an_unknown_tag");
    parent_copy.appendChild(blank_element);
    document.head.appendChild(parent_copy);
    var blank_style = getComputedStyle(blank_element);

    for (var dctr = 0; dctr < blank_style.length; dctr++) {
        if (dctr < cur_style.length) {
            var dname = blank_style[dctr];
            var dval = blank_style.getPropertyValue(dname);
			var cval = cur_style.getPropertyValue(dname);
            if (cval != dval && cur_elt.style[dname] != dval) {
                cur_elt.style[dname] = cval;
                }
            }
        }
    }

  module.exports = computedStyleToInlineStyle;
});
(function(){
	var h = document.createElement('div');
	var t = document.getElementsByTagName('title')[0];
	var cite_remove = '<a href="%23" onclick="document.body.firstChild.style.visibility = \'hidden\';document.body.firstChild.style.height = \'0px\';return false">remove</a>';
	var info = '<p><strong>Title(' + t.innerHTML.length + '):</strong> ' + t.innerHTML + '</p>';
	var m = document.getElementsByTagName('meta');
	for(var i = 0; i < ((m == null) ? 0 : m.length); i++) {
		if(null !== m[i].getAttribute('name') ) {
			var c=m[i].getAttribute('content');
			if (c != null) {info += '<p><strong>' + m[i].getAttribute('name') + '(' + c.length + '):</strong> ' + c + '</p>';}
			}
		}
	
	var lm = document.lastModified;
	var url = location.href;
	var d = new Date();
	var dd = d.getDate();
	var mm = d.getMonth()+1;
	var yyyy = d.getFullYear();
	info += '<p><strong>Citation: </strong>"' + t.innerHTML + '." Last modified ' + lm + '. <a target="_blank" href="' + url + '">' + url + '</a> (accessed ' + mm + '/' + dd + '/' + yyyy + ').</p><p><strong>Filename:</strong> ' + '0'.repeat(4-yyyy.toString().length) + yyyy + 'm'+'0'.repeat(2-mm.toString().length) + mm + 'd' + '0'.repeat(2-dd.toString().length) + dd + ' ' + url.replace('http://','').replace('https://','').replace('file:///','').replaceAll('/','-fslash-') + '.html</p>';
	document.body.insertBefore(h,document.body.firstChild);
	h.innerHTML='<div style="border:1px solid %23888;border-radius:5px;-moz-box-shadow:0 0 5px %23888;-webkit-box-shadow:0 0 5px%23888;box-shadow:0 0 5px %23888;background:%23eee;text-align:left;padding:1em;">' + cite_remove + info + cite_remove + '</div>';
	})();
document.querySelectorAll('iframe,script,noscript').forEach(function(element){element.parentNode.removeChild(element)});
computedStyleToInlineStyle(1, null, document.body);
document.head.parentNode.removeChild(document.head);
document.querySelectorAll('link').forEach(function(element){element.parentNode.removeChild(element)});
alert("done");

JavaScriptBookmarklets\Edit current page

Edit webpage

```
javascript:document.body.contentEditable = 'true'; document.designMode='on'; void 0
```

Editing Done

```
javascript:document.body.contentEditable = 'false'; document.designMode='off'; void 0
```

JavaScriptBookmarklets\Extract iFrame pages

JavaScriptCode HTMLCode Extract FileSystem
```
(function(){ var imgs = document.getElementsByTagName('iframe'),t=[]; for (var i=0, n=imgs.length;i'+ imgs[i].src+''); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract images

JavaScriptCode HTMLCode Extract FileSystem
```
avascript:(function(){ var imgs = document.getElementsByTagName('img'),t=[]; for (var i=0, n=imgs.length;i<n;i++) t.push('<a href="'+imgs[i].src+'"><img src="'+ imgs[i].src+'" width="100"></a>'); if (t.length) { var w=window.open('','_blank'); if (w) {w.document.write(t.join(' '));w.document.close();} else alert('cannot pop a window'); } })();

JavaScriptBookmarklets\Extract plain text

JavaScriptCode Extract Text
Copy the HTML body to a new window, so CSS and Javascript are ignored

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML;void(newWindow.focus());}
```

Copy the HTML body to a new window showing the HTML tags, so you can see the HTML code

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/&/g,"&amp;").replace(/</g,"<br>&lt;");void(newWindow.focus());}
```

Copy the HTML body without any HTML tags, so the text is loaded without any HTML or CSS styling

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){newWindow.document.documentElement.innerHTML=document.body.innerHTML.replace(/<[^>]+>/g, '<br>');void(newWindow.focus());}
```

JavaScriptBookmarklets\Unescape HTML code

```
avascript:document.documentElement.innerHTML='<html><body>'+document.body.innerHTML.replaceAll('&lt;','<').replaceAll('&gt;','>').replaceAll('&amp;','&')+'<\/body><\/html>';

JavaScriptBookmarklets\View HTML Source

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){;newWindow.document.documentElement.innerHTML='<html><head><title>Source of Page<\/title><\/head><body><pre>'+document.documentElement.outerHTML.replaceAll('&','&amp;').replaceAll('<','&lt;')+'<\/pre><\/body><\/html>';newWindow.document.body.contentEditable = 'true'; newWindow.document.designMode='on';void(newWindow.focus());}

JavaScriptBookmarklets\View HTML to TW

```
avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){;newWindow.document.documentElement.innerHTML='<html><head><title>Source of Page<\/title><\/head><body><pre>'+document.documentElement.outerHTML.replaceAll('&','&amp;').replaceAll('<','&lt;').replaceAll('&lt;html','&lt;div').replaceAll('&lt;\/html','&lt;\/div').replaceAll('&lt;body','&lt;div').replaceAll('&lt;\/body','&lt;\/div').replaceAll('position: absolute','position: relative').replaceAll('position: fixed','position: relative').replaceAll('position: flex','position: relative').replaceAll('>remove&lt;\/a>','&gt;&lt\/a&gt;').replaceAll('src="http','src_attr="http').replaceAll('src=\'http','src_attr=\'http')+'<\/pre><\/body><\/html>';newWindow.document.body.contentEditable = 'true'; newWindow.document.designMode='on';void(newWindow.focus());}

keyboard action FontLarge

$:/tags/KeyboardShortcut $:/positivesigner/text-ref
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/fontsize" text="24px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/lineheight" text="30px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize" text="25px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodylineheight" text="34px"/>

keyboard action FontNormal

$:/tags/KeyboardShortcut $:/positivesigner/text-ref
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/fontsize" text="14px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/lineheight" text="20px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodyfontsize" text="15px"/>
<$action-setfield $tiddler="$:/themes/tiddlywiki/vanilla/metrics/bodylineheight" text="24px"/>

keyboard action HomeTiddlers

$:/tags/KeyboardShortcut $:/positivesigner/home-button
<$action-sendmessage $message="tm-home"/>

keyboard action Preview

$:/tags/KeyboardShortcut META
<$list filter="[[$:/state/showeditpreview]get[text]!match[yes]]"><$action-setfield $tiddler="$:/state/showeditpreview" text="yes"/></$list>
<$list filter="[[$:/state/showeditpreview]get[text]match[yes]]"><$action-setfield $tiddler="$:/state/showeditpreview" text="no"/></$list>


keyboard action SaveAllChanges

$:/tags/KeyboardShortcut $:/positivesigner/base-install
\define ExportSaveAll(ur_filename, ur_stamp, ur_save_wiki_extension, ur_save_export_html)
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" filename="WikiMove_$ur_filename$-stamp-$ur_stamp$$ur_save_wiki_extension$"
/>
<$list variable=save_export_html filter="[[$ur_save_export_html$]match[1]]">
<$list variable=save_as_html_path filter="[[$ur_filename$]split[-fslash-src-fslash-]join[-fslash-]addprefix[WikiMove_]addsuffix[-stamp-$ur_stamp$.html]]">
<$action-sendmessage $message="tm-download-file"
$param="$:/core/templates/exporters/StaticRiver" filename=<<save_as_html_path>>
exportFilter="""[all[tiddlers]tag[INDEX]sort[title]][all[tiddlers]!tag[EXT]!tag[INDEX]!tag[META]!tag[MCR]!prefix[Draft of]!is[image]!is[tag]!is[system]sort[title]]"""/>
</$list><!--save_as_html_path-->
</$list><!--save_export_html-->
<$action-sendmessage $message="tm-download-file"
$param="template ExportAllCode" filename="WikiMove_$ur_filename$-stamp-$ur_stamp$.card.txt" />
\end
<$list variable=save_export_html filter="[{$:/info/url/full}suffix[.htm]count[]] [[parm SkipSaveExportHTML]is[tiddler]count[]multiply[-1]] +[sum[]]">
<$list variable=save_wiki_extension filter="[{$:/info/url/full}split[.]last[]addprefix[.]]">
<$list variable=save_as_file_name filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.html]join[]split[.htm]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<save_as_file_name>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> ur_save_wiki_extension=<<save_wiki_extension>> ur_save_export_html=<<save_export_html>> />
</$list><!--save_as_file_name-->
</$list><!--save_wiki_extension-->
</$list><!--save_export_html-->

mcr glbl_article_list

$:/tags/Macro $:/positivesigner/text-ref
\define glbl_article_list()
<ol>
<$list variable=card_prefix filter="[<currentTiddler>addsuffix[\]]">
<$list variable=cur_card filter="[prefix<card_prefix>sort[]]">
<$list variable=disp_name filter="[<cur_card>split[\]butfirst[]join[\]]">
<li><$link to=<<cur_card>> ><<disp_name>></$link></li>
</$list><!--disp_name-->
</$list><!--cur_card-->
</$list><!--card_prefix-->
</ol>
\end
\define glbl_article_checklist()
<$vars cur_card=<<currentTiddler>> >
<<glbl_dt_ddd>>
<$wikify name=cur_date text="""<<now "YYYYm0MMd0DD">>""" >
<$list variable=diff_date filter="[<cur_card>get[match_date]else[]!match<cur_date>]">
<$button>
<$list variable=field_name filter="[<cur_card>fields[]prefix[chk_]]">
<$action-setfield $field=<<field_name>> $value="" />
</$list><!--field_name-->
<$action-setfield match_date=<<cur_date>> />
Clear all checkmarks
</$button>
</$list><!--diff_date-->
</$wikify><!--cur_date-->
<ol>
<$list variable=card_prefix filter="[<cur_card>addsuffix[\]]">
<$list variable=cur_entry filter="[prefix<card_prefix>sort[]]">
<$list variable=disp_name filter="[<cur_entry>split[\]last[]]">
<$list variable=chk_name filter="[<disp_name>addprefix[chk_]split[ ]join[_]lowercase[]]">
<li>
<$checkbox default="no" unchecked="no" checked="yes" tiddler=<<cur_card>> field=<<chk_name>> >
<$link to=<<cur_entry>> ><<disp_name>></$link>
</$checkbox>
</li>
</$list><!--chk_name-->
</$list><!--disp_name-->
</$list><!--cur_card-->
</$list><!--card_prefix-->
</ol>
</$vars>
\end

mcr glbl_code_split

$:/tags/Macro $:/positivesigner/text-ref
\define glbl_code_block(ur_note_pk)
[[$ur_note_pk$]]
<$codeblock code={{$ur_note_pk$}} />
\end
\define glbl_code_linenum(ur_note_pk, ur_skip_count, ur_section_size, ur_disp_linenum)
<div style="clear:both">[[$ur_note_pk$]]</div>
<$list filter="[[$ur_skip_count$]!match[]else[0]]" variable=intSKIP_COUNT>
<$list filter="[[$ur_note_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>count[]]" variable=intLINE_COUNT>
<$list filter="[[$ur_section_size$]!match[]!match[0]else<intLINE_COUNT>]" variable=intSECTION_SIZE>
<$list filter="[range<intSECTION_SIZE>]" variable=intCUR_LINE>
<$list filter="[<intCUR_LINE>subtract[1]]" variable=IntREMOVE_LINE>
<$list filter="[[$ur_note_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>butfirst<IntREMOVE_LINE>first[]]" variable=strCUR_LINE>
<$list filter="[[$ur_disp_linenum$]!match[n]!match[0]]"><div style="float:left"><<intCUR_LINE>></div></$list>
<$codeblock code=<<strCUR_LINE>> />
</$list></$list></$list></$list></$list></$list>
\end
\define glbl_code_split_group(ur_note_pk, ur_skip_count)
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]splitregexp[\u0009]join[__	__]splitregexp[\u0020]join[__ __]splitregexp[\u0022\u0022\u0022]join[&#x0022;&#x0022;&#x0022;]]"><<currentTiddler>>
</$list></$list>
\end
\define glbl_code_split_count(ur_note_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_split_group ur_note_pk="$ur_note_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_split_data()
<$macrocall $name=glbl_code_split_count ur_note_pk=<<source_note_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_split_next_group_disp(ur_rem_counter)
<$list filter="[{$ur_rem_counter$}subtract[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_split_disp(ur_source_note_pk, ur_temp_note_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_note_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to find: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
Source data: [[$ur_source_note_pk$]]<br>
\end
\define glbl_code_split_combine()
$(currentTiddler)$$(str_html_out)$
\end
\define glbl_code_split_init(ur_note_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_note_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]add[1]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_note_pk>> text="" />
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_split(ur_note_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_split_init ur_note_pk="$ur_note_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_note_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_split_disp ur_source_note_pk=<<source_note_pk>> ur_temp_note_pk=<<temp_note_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$wikify name=str_html_out text=<<glbl_code_split_data>> >
        <$list filter="[<temp_note_pk>get[text]else[]]"><$vars combine_html_out=<<glbl_code_split_combine>> >
        <$action-setfield $tiddler=<<temp_note_pk>> text=<<combine_html_out>> />
         </$vars></$list>
        <$macrocall $name=glbl_code_split_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> />
        </$wikify>
      
      Find next 100 lines
      </$button><br>

    <$edit-text tiddler=<<temp_note_pk>> autoHeight=no />
    </$vars>
  </$list>
\end
\define glbl_code_disp_group(ur_note_pk, ur_skip_count)
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u00A0]join[&nbsp;]splitregexp[\u0009]join[&nbsp;&nbsp;&nbsp;&nbsp;]splitregexp[\u0020]join[&nbsp;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]]"><<currentTiddler>><br></$list></$list>
\end
\define glbl_code_disp_count(ur_note_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_note_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_disp_data()
<$macrocall $name=glbl_code_disp_count ur_note_pk=<<source_note_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_disp_next_group_disp(ur_rem_counter, ur_oper)
<$list filter="[{$ur_rem_counter$}$ur_oper$[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_disp_disp(ur_source_note_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_note_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to browse: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
\end
\define glbl_code_disp_init(ur_note_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_disp(ur_note_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_disp_init ur_note_pk="$ur_note_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
[[$ur_note_pk$]]<br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_note_pk="$ur_note_pk$" temp_remcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_note_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_disp_disp ur_source_note_pk=<<source_note_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="subtract" />
      
      Browse next 100 lines
      </$button><br>
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="add" />
      
      Browse prev 100 lines
      </$button><br>

    <<glbl_code_disp_data>>
    </$vars>
  </$list>
\end

<!--<$macrocall $name=glbl_code_disp ur_note_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_disp "WebNotes\Data 1 >>-->

<!--Does not pass through the \u0009 tab or \u00A0 non-breaking space characters. Chrome highlight and copy puts spaces on the clipboard.-->

<!--[[WebNotes\Data]]-->

<!--<$macrocall $name=glbl_code_split ur_note_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_block "UrNotePK">>-->

<!--<<glbl_code_linenum "UrNotePK" 0 15 n>>-->

mcr glbl_compare_lines

$:/tags/Macro $:/positivesigner/text-ref
\define glbl_compare_lines_results_table(ur_note_pk, ur_second_pk, ur_row_count)
<table><tr>
<th>''Line''</th>
<th>Show text</th>
<th>First Side<br>Second Side</th>
</tr>
<$list filter="[range<intSECOND_COUNT>subtract[1]]" variable="intCUR_ENTRY">
<$list filter="[{$ur_note_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]]" variable="strFIRST_LINE">
<$list filter="[{$ur_second_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]!match<strFIRST_LINE>]" variable="strSECOND_LINE">
<tr>
<td rowspan=2>

!!<<intCUR_ENTRY>>
</td>
<td>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/CompareTextSection1" text="""<$edit-text tiddler="$:/state/CompareTextLine1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/CompareTextLine1}!match[]else[0]]" variable=intSTART_LINE><$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine1" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_note_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_note_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/CompareTextSection1"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strFIRST_LINE>> /></td>
</tr>
<tr>
<td>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/CompareTextSection2" text="""<$edit-text tiddler="$:/state/CompareTextLine2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/CompareTextLine2}!match[]else[0]]" variable=intSTART_LINE>
<$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/CompareTextLine2" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_second_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_note_pk="$ur_second_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/CompareTextSection2"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strSECOND_LINE>> /></td>
</tr>
</$list></$list></$list>
</table>
\end
\define glbl_compare_lines(ur_note_pk, ur_second_pk)
<$list filter="[{$ur_note_pk$}splitregexp[\n]count[]]" variable="intFIRST_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]]" variable="intSECOND_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]subtract<intFIRST_COUNT>]" variable="intSECOND_EXTRA">

[[$ur_note_pk$]] line count: <<intFIRST_COUNT>>

[[$ur_second_pk$]] line count: <<intSECOND_COUNT>>

''$ur_second_pk$'' excess line count: ''<<intSECOND_EXTRA>>''

<$macrocall $name=glbl_compare_lines_results_table ur_note_pk="$ur_note_pk$" ur_second_pk="$ur_second_pk$" ur_row_count=<<intSECOND_COUNT>> />
</$list>
</$list>
</$list>
\end

<!--
<$edit-text tiddler="$:/state/CompareText1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>
<$edit-text tiddler="$:/state/CompareText2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>

<<glbl_compare_lines "$:/state/CompareText1" "$:/state/CompareText2">>
-->

mcr glbl_dt_ddd

$:/tags/Macro $:/positivesigner/text-ref
\define glbl_dt_ddd()
<div style="clear:right;float:right;background-color:aquamarine;"><<now "YYYYm0MMd0DD DDD pm0hh12\m0mm">></div>
<$list filter="[<currentTiddler>split[Draft of ']join[]split[ ]first[]split[m]join[]split[d]join[]]">
<$view field="title" format="date" template="[UTC]DDD" />
</$list>
\end

mcr glbl_ext

$:/tags/Macro $:/positivesigner/text-ref
\define ext(ur_extnote_pk)
<$list variable=missing_entry filter="[[ext $ur_extnote_pk$]get[text]else[]match[]]">Missing: [$ur_extnote_pk$]
</$list><!--missing_entry-->
<$list variable=prefix_dir filter="[{$:/info/url/full}split[/src/]count[]match[2]then[../]else[]]">
<$list variable=found_entry filter="[[ext $ur_extnote_pk$]get[text]else[]addprefix<prefix_dir>]">
<a target="_blank" href=<<found_entry>> >$ur_extnote_pk$</a><div style="float:right">[[->|ext $ur_extnote_pk$]]</div>
</$list><!--found_entry-->
</$list><!--prefix_dir-->
\end

MicrosoftRemoteDesktop

DOC
<<glbl_article_list>>

MicrosoftRemoteDesktop\Setup PC

WindowsOS AndroidOS UserAction
<<ext "Microsoft RemoteDesktop Enable">>

Panel

$:/positivesigner/text-ref
* https://github.com/settings/tokens
>* If there is an existing personal access token,
>>* Click on the name -> Navigates page
>>* Click button Regenerate Token -> Navigates page
>>* Click button Copy to Clipboard
>* Otherwise create a new token
* https://github.com/settings/tokens/new
>* Note = name of end user and device
>>* Must be unique
>>* Each device should get a different token
>* checkbox "repo" = set
>* Click button Generate token -> Navigates page
>* Click button Copy to Clipboard
!!
* <$link to="$:/ControlPanel" />
>* [Saving tab, GitHub Saver sub-tab]
>* Paste into field "Password, OAUTH token, or personal access token"
>* Close the Control Panel card
!!
* Click button <$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" />
Save Wiki
</$button>
>* Wait a few seconds for the "Saved wiki" notification
>* The token is saved in internal browser storage
>* If you get a "401" error, go back to step 1 to generate a new token

Recent Entries

$:/positivesigner/text-ref
[[Search All Fields]]

[[Tags Count Audit]]

[[View All Cards]]

[[View All Code]]

[[Font Size]]

<<timeline limit:30 format:"YYYY-0MM-0DD">>

Regular Expressions

DOC
<<glbl_article_list>>

Regular Expressions\Explanation

RegExCode CodeLibrary
\define disp_re(ur_list, ur_re)
<$vars re="$ur_re$">
`$ur_list$` matches `$ur_re$`?
<$list variable=ret filter="[[$ur_list$]regexp<re>else[no]]"> -,/<<ret>>\,- </$list>

`$ur_list$` split out `$ur_re$`?
<$list variable=ret filter="[[$ur_list$]splitregexp<re>]"> -,/<<ret>>\,- </$list></$vars>
<!--
disp_re-->
\end
[[TiddlyWiki\Regular Expression]]

<<ext "Regexp Filter with brackets">>

<<<
The code would get complexer ^^[sic]^^ too as "[''''[...]'''']" can't be put directly in the regex in TW. You'd have to do it through a variable. And since "[character class]" is reserved in regex you'd also have to escape square brackets "[\[\]]".
<<<

<<ext "Regular Expression Quantifiers">>

Regular expressions take a string of text, and returns a YES or NO as to whether it matches a character pattern.

You can specify a literal character.

* A letter or series of letters
** <<disp_re "ABC" "B">>
* `\`. is a literal period, because without the \ escape it would have special meaning
** <<disp_re "AA.AA" "\.">>

You can use tokens to specify a kind of character to match.

* `\d` is a numeric digit 0 through 9
** <<disp_re "A2C" "\d">>

* `\D` is any non-numeric digit
** <<disp_re "5A8" "\D">>

* `\s` is a whitespace character; like space, tab, or line feed
** <<disp_re "A C" "\s">>

* `\S` is a non-whitespace character
** <<disp_re "A" "\S">>

* `\W` is a whitespace or punctuation character (non-word character)
** <<disp_re ";" "\W">>

* `\w` is a word character (non-whitespace and non-punctuation character)
** <<disp_re "A" "\w">>

* `.` period is any character
** <<disp_re "A" ".">>

You can get out of having to use the \ escape over a block of text if you prefer to type it out.

* `\QOne. Two. Three.\E`  treats anything between the delimiters as a literal string, like "One. Two. Three."
** Useful to escape metacharacters
** Otherwise the periods would be special characters applied to the one letter before each period
** You can also write it as `One\. Two\. Three\.`

A regex quantifier such as `+` tells the regex engine to match a certain quantity of the character, token or subexpression immediately to its left.

* `A+` the quantifier + applies to A
** <<disp_re "AAABCCC" "B+">>
** <<disp_re "AAABBBCCC" "B+">>
* `A*` the quantifier * applies to A
** <<disp_re "ABBBC" "B*">>
** <<disp_re "AC" "B*">>
* `ABC?` the quantifier `?` applies to the C—not to ABC
** <<disp_re "ABCD" "BC?">>
** <<disp_re "ABD" "BC?">>
* `(?:A|B|C)+` the quantifier + applies to the subexpression
** <<disp_re "ABCD" "(?:B|C)+">>
** <<disp_re "ABD" "(?:B|C)+">>
* `\QA.B.C\E+` is treated as a sequence of literals, so the quantifier only applies to the last character
** This could also be written as `A\.B\.C+`

By default, a quantifier tells the engine to match as many instances of its quantified token or subpattern as possible. This behavior is called greedy.

* `A+` is greedy, and matches all the number characters in a row from the starting point where exists (a number)
** <<disp_re "ABBBCD" "B+">>
* `A+B` is greedy, and matches all the number characters in a row where exists (a letter B after a letter A)
** <<disp_re "ABBBCD" "B+C">>
** <<disp_re "ABBBCD" "(B+)C">>

In contrast to the standard greedy quantifier, which eats up as many instances of the quantified token as possible, a lazy (sometimes called reluctant) quantifier tells the engine to match as few of the quantified tokens as needed.

* `\w*?B` is lazy, and matches as few word characters in a row as needed where exists (a letter B after a word character)
** <<disp_re "+ABCCC+" "\w*?C">>
** <<disp_re "+ABCCC+" "\w*C">>

In contrast to the standard docile quantifier, which gives up characters if needed in order to allow the rest of the pattern to match, a possessive quantifier tells the engine that even if what follows in the pattern fails to match, it will hang on to its characters.

* A++ is possessive—it matches as many characters as needed and never gives any of them back.
** Whereas the regex A+. matches the string AAA, A++. doesn't. At first, the token A++ greedily matches all the A characters in the string. The engine then advances to the next token in the pattern. The dot . fails to match because there are no characters left to match. The engine looks if there is something to backtrack. But A++ is possessive, so it will not give up any characters. There is nothing to backtrack, and the pattern fails. In contrast, with A+., the A+ would have given up the final A, allowing the dot to match.

You can specify a number range of characters to repeat.

* A{2,9} uses two to nine As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
** <<disp_re "+ABCCC+" "C{1,2}">>
** <<disp_re "+ABCCC+" "C{2,2}">>
** <<disp_re "+ABCCC+" "C{2,9}">>
* A{2,} uses two or more As, as many as possible (greedy), giving up characters if the engine needs to backtrack (docile)
** <<disp_re "+ABCCC+" "C{2,}">>

You can use negated character classs to match characters other up to the one you want.

* `^[^\.]*` skips up to first period
** <<disp_re "AB.C.D" "^[^\.]*">>
* `^.*\.` skips up to last period
** <<disp_re "AB.C.D" "^.*\.">>

Tempered Greedy Token Solution

* `A(?:(?!B).)*B` stops at the first B instead of the last B
** <<disp_re "AB.C.DCE" "B(?:(?!C).)*C">>
** <<disp_re "AB.C.DCE" "B.*C">>

* `A(?:(?!C)(?!B).)*B` stops at the first B unless there is a C between the A and B
** <<disp_re "AB.CA" "B(?:(?!D)(?!C).)*C">>
** <<disp_re "AB.CAB.FGHBC" "B(?:(?!D)(?!C).)*C">>
** <<disp_re "AB.CAB.DFGHBC" "B(?:(?!D)(?!C).)*C">>

Search All Fields

$:/positivesigner/text-ref
<$vars search_text_pk="$:/state/popup/SearchAllFields">
<$list variable=show_code_pk filter="[<search_text_pk>addsuffix[-checkShowCode]]">
<$list variable=skip_system_pk filter="[<search_text_pk>addsuffix[-checkSkipSystem]]">
<$edit-text tiddler=<<search_text_pk>> field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler=<<skip_system_pk>>> Skip System </$checkbox><br>
<br>

<$list variable=cur_search_text filter="[<search_text_pk>get[text]addsuffix[(?i)]!match[]]">
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]else[no]]">
<$list variable=cur_skipsystem_text filter="[<skip_system_pk>get[text]else[yes]match[yes]count[]]">

<!--Card titles-->
<$list variable=cur_pk filter="[regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_skipsystem_text>] [<cur_pk>!is[system]count[]] +[sum[]match[1]]">

<$link to=<<cur_pk>> />: title
</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

<!--Card fields-->
<$list variable=cur_pk filter="[!regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_pk>is[system]count[]multiply<cur_skipsystem_text>match[0]]">
<$list variable=cur_field filter="[<cur_pk>fields[]]">
<$list variable=found_field filter="[<cur_pk>get<cur_field>regexp<cur_search_text>]">

<$link to=<<cur_pk>> />: <<cur_field>>
<$list variable=disp_code filter="[<cur_showcode_text>match[yes]]">
<$codeblock code=<<found_field>> />
</$list><!--disp_code-->
</$list><!--found_field-->
</$list><!--cur_field-->

</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

</$list><!--cur_skipsystem_text-->
</$list><!--cur_showcode_text-->
</$list><!--cur_search_text-->
</$list><!--skip_system_pk-->
</$list><!--show_code_pk-->
</$vars><!--search_text_pk-->

SQLite

DOC
<<glbl_article_list>>

SQLite\Blob text

SQLCode AssignVariable Filter
<<ext "SQLite Blob text">>

```
WITH RECURSIVE test(c,cur) as (
     SELECT '', HEX(blob_field) FROM UrTable WHERE UrPK = 6
   UNION ALL
    select c || char((case substr(cur,1,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,1,1) end)*16
               + (case substr(cur,2,1) when 'A' then 10 when 'B' then 11 when 'C' then 12 when 'D' then 13 when 'E' then 14 when 'F' then 15 else substr(cur,2,1) end)),
substr(cur,3)
from test where length(cur)>0
)
select * from test
```

SQLite\Database Browser

SQLCode FileSystem Extract WindowsOS
<<ext "SQLite DB Browser">>

I used `DB Browser for SQLite - .zip (no installer) for 64-bit Windows`

SQLite\Information Schema

SQLCode FileSystem Extract
<<ext "SQLite schema information">>

```
SELECT name, sql FROM sqlite_master
WHERE type='table'
ORDER BY name;
```

<<ext "SQLite Language functions">>

sqlite_source_id()

```
--version string of SQLite Library source code
2020-08-14 13:23:32 fca8dc8b578f215a969cd899336378966156154710873e68b3d9ac5881b0ff3f
```

sqlite_version()

```
--version string of SQLite Library running
3.33.0
```

SQLite\String Manipulation

SQLCode Extract Text
<<ext "SQLite Language functions">>

```
--comment
```

CHAR(unicode_char_list)

COALESCE(field_list)

HEX(field)

IFNULL(field, default_text)

INSTR(field, search_text)

LENGTH(field)

LIKE(field, comparison_text)

* field LIKE comparisontext
* LIKE(field, comparison_text, escape_char)

LOWER(field)

LTRIM(field)

* LTRIM(field, chars_to_remove)

PRINTF(format_text, field_list)

REPLACE(field, search_text, new_text)

RTRIM(field)

* RTRIM(field, chars_to_remove)

SUBSTR(field, start_char)

* SUBSTR(field, start_char, char_count)

TRIM(field)

* TRIM(field, chars_to_remove)

typeof(field)

* "null", "integer", "real", "text", or "blob".

UNICODE(number)

UPPER(field)

SQLite\Top or Limit records

SQLCode Numbers Filter
<<ext "SQLite Top 5 Records">>

SELECT * FROM Table_Name LIMIT 5;

Tags Count Audit

$:/positivesigner/text-ref
<$list variable=cur_card filter="[!has[tags]!prefix[$:]]">

<$link to=<<cur_card>> />
</$list><!--cur_card-->

---
<$list variable=cur_card filter="[!tag[DOC]!tag[EXT]!tag[IMG]!tag[INDEX]!tag[META]has[tags]!prefix[$:]]">
<$list variable=filter_tag_count filter="[<cur_card>tags[]butfirst[]first[]count[]match[0]]">

<$link to=<<cur_card>> />
</$list><!--filter_tag_count-->
</$list><!--cur_card-->

template ExportAllCode

$:/tags/Exporter $:/positivesigner/base-install
\define renderContent()
<$list variable=cur_tip_pk filter="[all[tiddlers]!has[draft.of]!is[image]has[tags]!prefix[undefined]] [!prefix[$]!has[draft.of]!is[image]!has[tags]!prefix[undefined]] +[sort[title]]">
<hr>
<h2><$link to=<<cur_tip_pk>> /></h2>
<$list variable=cur_tip_text filter="[<cur_tip_pk>get[text]]">
<$codeblock code=<<cur_tip_text>> />
</$list><!--cur_tip_text-->
</$list><!--cur_tip_pk-->
\end
<<renderContent>>

template Home Button

$:/tags/ViewTemplate $:/positivesigner/home-button
<$list variable=on_twcard filter="[<tv-config-toolbar-icons>!match[no]]">
<div style="float:right;padding-left:30px;">
{{$:/core/ui/TopBar/menu}}
</div>

<div style="float:right"><$button set="$:/state/sidebar" setTo="no" tooltip={{$:/language/Buttons/Home/Hint}} aria-label={{$:/language/Buttons/Home/Caption}} class=<<tv-config-toolbar-class>>>
<span class="tc-dirty-indicator">
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{$:/core/images/home-button}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text={{$:/language/Buttons/Home/Caption}}/></span>
</$list>
</span>
<$action-sendmessage $message="tm-home"/>
</$button></div>
</$list><!--on_twcard-->

TiddlyWiki

DOC
<<glbl_article_list>>

TiddlyWiki\Add Tag to All Cards

TWCard AssignVariable FileSystem
```
<$button>
<$action-setfield $tiddler="Test1" tags="COPY"/>
Reset Test1 Card's Tag list with just COPY
</$button>

<$button>
<$list variable=cur_card filter="[is[tiddler]!prefix[$:/state/]]">
<$list variable=has_tag filter="[<cur_card>tags[]count[]!match[0]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[append[COPY]]"/>
</$list>
</$list>
Append COPY tag to all Cards that already have tags
</$button>

<$button>
<$list variable=cur_card filter="[tag[COPY]]">
<$action-listops $tiddler=<<cur_card>> $tags="+[remove[COPY]]"/>
</$list>
Remove COPY tag from all Cards
</$button>

TiddlyWiki\Backlink to HTML,HTM

TWCard FileSystem CodeLibrary
Title = ext TW Return

```
\define TW_Return(ur_url, ur_link_title)
<div style="float:right"><a href="$ur_url$"> ($ur_link_title$)</a></div>
\end
<$list filter="[<tv-config-toolbar-icons>match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="TiddlyWiki view of website" />
</$list>
</$list>
<$list filter="[<tv-config-toolbar-icons>!match[no]]">
<$list filter="[{$:/info/url/full}split[.html]join[.htm]split[.htm]join[.html]]">
<$macrocall $name=TW_Return ur_url=<<currentTiddler>> ur_link_title="Static HTML view of website" />
</$list>
</$list>

TiddlyWiki\Button navigate to Card

TWCard UserAction FileSystem
```
<$vars new_code="Test1">
<$list variable=new_pk filter="[<new_code>addprefix[$:/state/popup/]]">
<$button>
<$action-sendmessage $message="tm-new-tiddler" title=<<new_pk>> tags="OneTag [[Another Tag]]" text=<<now "Today is DDth, MMM YYYY">>/>
Create Code ''<<new_code>>'' and Edit
</$button><br>

<$button>
<$action-setfield $tiddler=<<new_pk>> text="yes"/>
<$action-navigate $to=<<new_pk>>/>
Create Code ''<<new_code>>'' and Show
</$button><br>

<$link to=<<new_pk>> /><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
Close Code: ''<<new_code>>''
</$button><br>

<$list filter="[<currentTiddler>!prefix[Draft of]]" variable=strCARD_PK>
<$button>
<$list filter="[list[$:/StoryList]] -[<strCARD_PK>]" variable=strCLOSE_PK>
<$action-sendmessage $message="tm-close-tiddler" $param=<<strCLOSE_PK>>/>
</$list>
Close all other open Codes
</$button>
</$list><br>

<$button>
<$action-sendmessage $message="tm-delete-tiddler" $param=<<new_pk>> />
Delete Card: ''<<new_card>>'' with confirmation
</$button><br>

<$button>
<$action-sendmessage $message="tm-close-tiddler" $param=<<new_pk>> />
<$action-deletetiddler $tiddler=<<new_pk>> />
Delete Card: ''<<new_card>>'' without confirmation
</$button>
</$list><!--new_pk-->
</$vars><!--new_card-->

TiddlyWiki\Button Set Field

TWCard AssignVariable UserAction
```
<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="yes"/>
Set UrCardPK = yes
</$button>

<$button>
<$action-setfield $tiddler="$:/state/UrCardPK" text="no"/>
Set UrCardPK = no
</$button>

TiddlyWiki\Checkbox edit

TWCard AssignVariable UserAction
```
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler="$:/state/popup/checkUseIt">Use It</$checkbox>

TiddlyWiki\Clipboard Copy

TWCard AssignVariable UserAction
Tags = `$:/tags/Macro`

```
\define cboard_copy(ur_text)
<pre>$ur_text$</pre>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end
\define cboard_pwd(ur_text ur_pk)
<$reveal type="nomatch" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="show">Show</$button>

</$reveal>
<$reveal type="match" state="$:/state/popup/$ur_pk$" text="show">

<$button set="$:/state/popup/$ur_pk$" setTo="hide">Hide</$button>
<pre>$ur_text$</pre>
</$reveal>
<span style="margin-left:30px">
<<copy-to-clipboard "$ur_text$">>
</span>
\end

TiddlyWiki\Code View or Copy data

TWCard CodeLibrary Extract
Title = `mcr glbl_code_split`

Tags = `$:/tags/Macro`

```
\define glbl_code_block(ur_card_pk)
[[$ur_card_pk$]]
<$codeblock code={{$ur_card_pk$}} />
\end
\define glbl_code_linenum(ur_card_pk, ur_skip_count, ur_section_size, ur_disp_linenum)
<div style="clear:both">[[$ur_card_pk$]]</div>
<$list filter="[[$ur_skip_count$]!match[]else[0]]" variable=intSKIP_COUNT>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>count[]]" variable=intLINE_COUNT>
<$list filter="[[$ur_section_size$]!match[]!match[0]else<intLINE_COUNT>]" variable=intSECTION_SIZE>
<$list filter="[range<intSECTION_SIZE>]" variable=intCUR_LINE>
<$list filter="[<intCUR_LINE>subtract[1]]" variable=IntREMOVE_LINE>
<$list filter="[[$ur_card_pk$]get[text]splitregexp[\n]butfirst<intSKIP_COUNT>butfirst<IntREMOVE_LINE>first[]]" variable=strCUR_LINE>
<$list filter="[[$ur_disp_linenum$]!match[n]!match[0]]"><div style="float:left"><<intCUR_LINE>></div></$list>
<$codeblock code=<<strCUR_LINE>> />
</$list></$list></$list></$list></$list></$list>
\end
\define glbl_code_split_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]splitregexp[\u0009]join[__	__]splitregexp[\u0020]join[__ __]splitregexp[\u0022\u0022\u0022]join[&#x0022;&#x0022;&#x0022;]]"><<currentTiddler>>
</$list></$list>
\end
\define glbl_code_split_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_split_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_split_data()
<$macrocall $name=glbl_code_split_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_split_next_group_disp(ur_rem_counter)
<$list filter="[{$ur_rem_counter$}subtract[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_split_disp(ur_source_card_pk, ur_temp_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to find: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
Source data: [[$ur_source_card_pk$]]<br>
\end
\define glbl_code_split_combine()
$(currentTiddler)$$(str_html_out)$
\end
\define glbl_code_split_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]add[1]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_card_pk>> text="" />
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_split(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_split_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_card_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesOutput" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_split_disp ur_source_card_pk=<<source_card_pk>> ur_temp_card_pk=<<temp_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$wikify name=str_html_out text=<<glbl_code_split_data>> >
        <$list filter="[<temp_card_pk>get[text]else[]]"><$vars combine_html_out=<<glbl_code_split_combine>> >
        <$action-setfield $tiddler=<<temp_card_pk>> text=<<combine_html_out>> />
         </$vars></$list>
        <$macrocall $name=glbl_code_split_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> />
        </$wikify>
      
      Find next 100 lines
      </$button><br>

    <$edit-text tiddler=<<temp_card_pk>> autoHeight=no />
    </$vars>
  </$list>
\end
\define glbl_code_disp_group(ur_card_pk, ur_skip_count)
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst[$ur_skip_count$]first[100]]"><$list filter="[<currentTiddler>splitregexp[\u0026]join[&#x0026;]splitregexp[\u00A0]join[&nbsp;]splitregexp[\u0009]join[&nbsp;&nbsp;&nbsp;&nbsp;]splitregexp[\u0020]join[&nbsp;]splitregexp[\u0027]join[&#x0027;]splitregexp[\u002C]join[&#x002C;]splitregexp[\u002D]join[&#x002D;]splitregexp[\u002F]join[&#x002F;]splitregexp[\u003A]join[&#x003A;]splitregexp[\u003C]join[&#x003C;]splitregexp[\u0040]join[&#x0040;]splitregexp[\u005B]join[&#x005B;]splitregexp[\u005C]join[&#x005C;]splitregexp[\u005E]join[&#x005E;]splitregexp[\u005F]join[&#x005F;]splitregexp[\u0060]join[&#x0060;]splitregexp[\u007B]join[&#x007B;]splitregexp[\u007E]join[&#x007E;]]"><<currentTiddler>><br></$list></$list>
\end
\define glbl_code_disp_count(ur_card_pk, ur_rem_counter, ur_last_counter, ur_first_line_skip)
<$list filter="[{$ur_last_counter$}subtract{$ur_rem_counter$}multiply[100]add[$ur_first_line_skip$]]"><$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$" ur_skip_count=<<currentTiddler>> /></$list>
\end
\define glbl_code_disp_data()
<$macrocall $name=glbl_code_disp_count ur_card_pk=<<source_card_pk>> ur_rem_counter=<<temp_remcounter_pk>> ur_last_counter=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
\end
\define glbl_code_disp_next_group_disp(ur_rem_counter, ur_oper)
<$list filter="[{$ur_rem_counter$}$ur_oper$[1]]">
<$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
</$list>
\end
\define glbl_code_disp_disp(ur_source_card_pk, ur_temp_remcounter_pk, ur_first_line_skip)
Line Count: <$list filter="[{$ur_source_card_pk$}splitregexp[\n]butfirst[$ur_first_line_skip$]count[]]"></$list><br>
Rem to browse: <$list filter="[{$ur_temp_remcounter_pk$}]"></$list><br>
\end
\define glbl_code_disp_init(ur_card_pk, ur_first_line_skip)
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<first_line_skip>count[]divide[100]floor[]]">
      <$button>
        <$action-setfield $tiddler=<<temp_remcounter_pk>> text=<<currentTiddler>> />
        <$action-setfield $tiddler=<<temp_lastcounter_pk>> text=<<currentTiddler>> />
        Reset destination edit field
        </$button>
      </$list><br>
	
    <$edit-text tiddler=<<temp_remcounter_pk>> autoHeight=yes tag=input />
    </$vars>
  </$list>
\end
\define glbl_code_disp(ur_card_pk, ur_first_line_skip)
<$macrocall $name=glbl_code_disp_init ur_card_pk="$ur_card_pk$" ur_first_line_skip="$ur_first_line_skip$" /><br>
[[$ur_card_pk$]]<br>
<$list filter="[[$ur_first_line_skip$]!match[]then[$ur_first_line_skip$]else[0]]">
  <$vars source_card_pk="$ur_card_pk$" temp_remcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesRemCounter" temp_lastcounter_pk="$:/state/popup/$ur_card_pk$/HtmlEscapedLinesLastCounter" first_line_skip=<<currentTiddler>> >
    <$macrocall $name=glbl_code_disp_disp ur_source_card_pk=<<source_card_pk>> ur_temp_remcounter_pk=<<temp_remcounter_pk>> ur_temp_lastcounter_pk=<<temp_lastcounter_pk>> ur_first_line_skip=<<first_line_skip>> />
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="subtract" />
      
      Browse next 100 lines
      </$button><br>
    <$button>
      <$macrocall $name=glbl_code_disp_next_group_disp ur_rem_counter=<<temp_remcounter_pk>> ur_oper="add" />
      
      Browse prev 100 lines
      </$button><br>

    <<glbl_code_disp_data>>
    </$vars>
  </$list>
\end

<!--<$macrocall $name=glbl_code_disp ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_disp "WebNotes\Data 1 >>-->

<!--Does not pass through the \u0009 tab or \u00A0 non-breaking space characters. Chrome highlight and copy puts spaces on the clipboard.-->

<!--[[WebNotes\Data]]-->

<!--<$macrocall $name=glbl_code_split ur_card_pk="WebNotes\Data" ur_first_line_skip=1 />-->

<!--<<glbl_code_block "UrCardPK">>-->

<!--<<glbl_code_linenum "UrCardPK" 0 15 n>>-->

TiddlyWiki\Codeblock Widget

TWCard Text Formatting CodeLibrary
\define sample_data_e1()
```
sample code "here" and "there"
```
\end

\define sample_data_e2()
<$codeblock code="""sample code "here" and "there"
"""/>
\end

\define sample_data_e3() \define sample_data_e3() sample code "here" and "there"

\define sample_data_e4()
\define sample_data_e4()
sample
code """here"""
and "there"
\end <--Last line of macro
\end

\define sample_data_e5()
<$codeblock code={{{ [[UrCardPK]get[text]] }}}/>
\end

<$codeblock code=<<sample_data_e1>>/>

You can use the `<$codeblock>` widget to display text as the three-backticks TiddlyWiki formatting block. Make sure to put an enter at the end of the string if it ends with d-quotes.

<$codeblock code=<<sample_data_e2>>/>

If you need to show text triple d-quotes in a code string, define a macro to return the string literal instead of passing in a code string.

<$codeblock code=<<sample_data_e3>>/>

Make sure to put a leading space or some trailing comment text on any line within the macro that has `\end` by itself. Otherwise the macro definition will end early.

<$codeblock code=<<sample_data_e4>>/>

Another way to display a Card's content is by using the triple-curly-brace inclusion.

<$codeblock code=<<sample_data_e5>>/>

TiddlyWiki\Compare Lines

TWCard Text Extract Formatting
```
<$diff-text source={{t1}} dest={{mcr glbl_section_disp}}/>
```

Name = mcr glbl_compare_lines

Tag = `$:/tags/Macro`

```
\define glbl_compare_lines_results_table(ur_card_pk, ur_second_pk, ur_row_count)
<table><tr>
<th>''Line''</th>
<th>Show text</th>
<th>First Side<br>Second Side</th>
</tr>
<$list filter="[range<intSECOND_COUNT>subtract[1]]" variable="intCUR_ENTRY">
<$list filter="[{$ur_card_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]]" variable="strFIRST_LINE">
<$list filter="[{$ur_second_pk$}splitregexp[\n]butfirst<intCUR_ENTRY>first[]!match<strFIRST_LINE>]" variable="strSECOND_LINE">
<tr>
<td rowspan=2>

!!<<intCUR_ENTRY>>
</td>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection1" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine1}!match[]else[0]]" variable=intSTART_LINE><$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine1" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_card_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_card_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection1"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strFIRST_LINE>> /></td>
</tr>
<tr>
<td>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intCUR_ENTRY>>/>
<$action-setfield $tiddler="$:/state/popup/CompareTextSection2" text="""<$edit-text tiddler="$:/state/popup/CompareTextLine2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=input/>
<$list filter="[{$:/state/popup/CompareTextLine2}!match[]else[0]]" variable=intSTART_LINE>
<$list filter="[<intSTART_LINE>subtract[1]]" variable=intPREV_LINE>
<$list filter="[<intSTART_LINE>add[1]]" variable=intNEXT_LINE>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intPREV_LINE>>/>
<<intPREV_LINE>>
</$button>
<$button>
<$action-setfield $tiddler="$:/state/popup/CompareTextLine2" text=<<intNEXT_LINE>>/>
<<intNEXT_LINE>>
</$button><br>[[$ur_second_pk$]]<br>
<$macrocall $name=glbl_code_disp_group ur_card_pk="$ur_second_pk$"  ur_skip_count=<<intSTART_LINE>> />
</$list></$list></$list>""" />
<$action-navigate $to="$:/state/popup/CompareTextSection2"/>
<<intCUR_ENTRY>>
</$button>
</td>
<td><$codeblock code=<<strSECOND_LINE>> /></td>
</tr>
</$list></$list></$list>
</table>
\end
\define glbl_compare_lines(ur_card_pk, ur_second_pk)
<$list filter="[{$ur_card_pk$}splitregexp[\n]count[]]" variable="intFIRST_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]]" variable="intSECOND_COUNT">
<$list filter="[{$ur_second_pk$}splitregexp[\n]count[]subtract<intFIRST_COUNT>]" variable="intSECOND_EXTRA">

[[$ur_card_pk$]] line count: <<intFIRST_COUNT>>

[[$ur_second_pk$]] line count: <<intSECOND_COUNT>>

''$ur_second_pk$'' excess line count: ''<<intSECOND_EXTRA>>''

<$macrocall $name=glbl_compare_lines_results_table ur_card_pk="$ur_card_pk$" ur_second_pk="$ur_second_pk$" ur_row_count=<<intSECOND_COUNT>> />
</$list>
</$list>
</$list>
\end

<!--
<$edit-text tiddler="$:/state/popup/CompareText1" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>
<$edit-text tiddler="$:/state/popup/CompareText2" field=text default="" placeholder="[no text yet]" autoHeight=no tag=textarea/>

<<glbl_compare_lines "$:/state/popup/CompareText1" "$:/state/popup/CompareText2">>
-->

TiddlyWiki\Construct a Calendar

TWCard Numbers Formatting Extract
```
\define CalendarEntryDay(ur_ymd,ur_d,ur_cur_date)
<$list filter='$ur_ymd$ +[match[$ur_cur_date$]]'>
//''<span style="background-color:yellow">$ur_ymd$</span>''//<br>
</$list>
<$list filter='[prefix[$ur_ymd$]count[]match[0]]'>
<$list filter='$ur_ymd$ +[!match[$ur_cur_date$]]'>
$ur_ymd$<br>
</$list>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]match[1]]">
''d$ur_d$''<br><<currentTiddler>> entry<br>
</$list>
<$list filter="[prefix[$ur_ymd$]count[]!match[0]!match[1]]">
''d$ur_d$''<br><<currentTiddler>> entries<br>
</$list>
\end

\define CalendarEntryMonth(ur_ym,ur_d,ur_cur_date)
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]!match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d0$ur_d$" ur_d="0$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$ur_d$]count[]match[0]]">
<$macrocall $name="CalendarEntryDay" ur_prefix=<<currentTiddler>> ur_ymd="$ur_ym$d$ur_d$" ur_d="$ur_d$" ur_cur_date="$ur_cur_date$" />
</$list>
\end

\define CalendarListDailyThings(day month year)
<$button class='tc-btn-invisible' style='width:100%;height:100%'>
<div style='height:100%;width:100%;position:relative;text-align:left;vertical-align:top;z-index=0'>

<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]!match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_ym="$year$m0$month$" ur_d="$day$"  ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>
<$list filter="0 1 2 3 4 5 6 7 8 9 +[match[$month$]count[]match[0]]">
<$macrocall $name="CalendarEntryMonth" ur_prefix=<<currentTiddler>> ur_m="$year$m$month$" ur_d="$day$" ur_cur_date=<<now YYYYm0MMd0DD>> />
</$list>


</div>
</$button>
\end
\define date_list_entry(ur_num,ur_cur_date)
<$list filter="[[$ur_num$]match[$ur_cur_date$]]">
//''<span style="background-color:yellow">$ur_cur_date$</span>''//<br>
</$list>
<$list filter="[prefix[$ur_num$]count[]!match[0]]">
<$list filter="[[$ur_num$]!match[$ur_cur_date$]count[]!match[0]]">
$ur_num$<br>
</$list>
</$list>
<<list-links filter:"[prefix[$ur_num$]]" >>
\end
\define date_list_dayunit(ur_num,ur_cur_date)
<$list filter="$ur_num$0 $ur_num$1 $ur_num$2 $ur_num$3 $ur_num$4 $ur_num$5 $ur_num$6 $ur_num$7 $ur_num$8 $ur_num$9">
<$macrocall $name="date_list_entry" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list_daydec(ur_year_month,ur_num,ur_cur_date)
<$list filter="$ur_year_month$d0 $ur_year_month$d1 $ur_year_month$d2 $ur_year_month$d3 $ur_year_month$d4 $ur_year_month$d5 $ur_year_month$d6 $ur_year_month$d7 $ur_year_month$d8 $ur_year_month$d9">
<$macrocall $name="date_list_dayunit" ur_num=<<currentTiddler>> ur_cur_date="$ur_cur_date$" />
</$list>
\end
\define date_list(ur_year,ur_month)
<$calendar-month year="$ur_year$" month="$ur_month$" />

<$macrocall $name="date_list_daydec" ur_year_month="$ur_year$m$ur_month$" ur_num=<<currentTiddler>> ur_cur_date=<<now YYYYm0MMd0DD>> />
\end

TiddlyWiki\Core Macro Definition

TWCard FileSystem Extract
* Title = `mcr glbl_core_mcr_def`
* Tag = `$:/tags/Macro`

```
\define glbl_core_mcr_def(ur_macro_name)
<$list variable=cur_pk filter="""[[$:/core]get[text]split[define $ur_macro_name$(]butfirst[]split[\n\\end]first[]addprefix[define $ur_macro_name$(]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">
<$codeblock code=<<cur_pk>> />
</$list><!--cur_pk-->
\end
```

* Show all Core macro names and source code

```
<$list variable=show_code_pk filter="[<currentTiddler>split[Draft of]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-checkShowCode]]">
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>

<$list variable=cur_def_text filter="[[$:/core]get[text]split[define ]!prefix[{]!prefix[the]sort[]]">
<$list variable=cur_macro_name filter="[<cur_def_text>split[(]first[]]">
<$list variable=cur_end_text filter="""[<cur_def_text>split[\n\\end]first[]addprefix[define ]addsuffix[\n\\end]split[\\]join[\]split[\"]join["]split[\n]join[
]]""">

!! <<cur_macro_name>>
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]match[yes]]"><$codeblock code=<<cur_end_text>> />
</$list><!--cur_showcode_text-->

</$list><!--cur_end_text-->
</$list><!--cur_macro_name-->
</$list><!--cur_def_text-->
</$list><!--show_code_pk-->
```

TiddlyWiki\CSS Classes

TWCard CSSCode Formatting
!! New Card page
* Card name = css alternating-rows
* Tag = $:/tags/Stylesheet

```
.alternating-rows tr:nth-child(even) {background-color:white}
.alternating-rows tr:nth-child(odd) {background-color:lightgrey}
```

Note: The @''''@ directive must include the leading period (.) to select a CSS class

```
@@.alternating-rows
<table>
<tr><th>hi</th></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>
<tr><td>hi</td></tr>

TiddlyWiki\CSS without classes

TWCard CSSCode Formatting
!! Apply stylesheet to all cards

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
.tc-tiddler-body {
  word-break: normal; 
  word-wrap: break-word;
  white-space: pre-wrap;
} 
```

* Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

!! Apply stylesheet to cards with specific tag `linewrap`

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

* Note: Only cards with the `linewrap` tag will use this stylesheet change

!! Apply Styles to In-line Text

* Start a text block with @,,,,@ and the CSS styles with no spaces

Sample Code:

```
@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line
```

<<<
Result:

```
These are
separate lines
here

This is one big line
```
<<<

* or start in the middle of a text block

Sample Code:

```
This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.
```

<<<
Result:

```
This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.
```
<<<

TiddlyWiki\Data Tiddler

TWCard AssignVariable FileSystem
Type = `application/x-tiddler-dictionary`

```
3:a
2:b
3:c
```

See list of unique indexes:

```
<$list variable=cur_key filter="[[UrPK]indexes[]]"><<cur_key>>: 
<$list variable=cur_val filter="[[UrPK]getindex<cur_key>]"><<cur_val>><br>
</$list><!--cur_val-->
</$list><!--cur_key-->
```

Use one value (last one if an index is duplicated):

```
-{{UrPK##3}}-


```

[[VBNetCode\Text file to JSON Lines]]

TiddlyWiki\Date Part

TWCard Numbers Extract Formatting
Tag = `$:/tags/Macro`

```
\define glbl_dt_ddd()
<div style="clear:right;float:right;background-color:aquamarine;"><<now "YYYYm0MMd0DD DDD pm0hh12\m0mm">></div>
<$list filter="[<currentTiddler>split[Draft of ']join[]split[ ]first[]split[m]join[]split[d]join[]]">
<$view field="title" format="date" template="[UTC]DDD" />
</$list>
\end
```

|!Token |!Substituted Value |
|`DDD` |Day of week in full (eg, "Monday") |
|`ddd` |Short day of week (eg, "Mon") |
|`DD` |Day of month |
|`0DD` |Adds a leading zero |
|`DDth` |Adds a suffix |
|`WW` |ISO-8601 week number of year |
|`0WW` |Adds a leading zero |
|`MMM` |Month in full (eg, "July") |
|`mmm` |Short month (eg, "Jul") |
|`MM` |Month number |
|`0MM` |Adds leading zero |
|`YYYY` |Full year |
|`YY` |Two digit year |
|`wYYYY` |Full year with respect to week number |
|`wYY` |Two digit year with respect to week number |
|`hh` |Hours |
|`0hh` |Adds a leading zero |
|`hh12` |Hours in 12 hour clock |
|`0hh12` |Hours in 12 hour clock with leading zero |
|`mm` |Minutes |
|`0mm` |Minutes with leading zero |
|`ss` |Seconds |
|`0ss` |Seconds with leading zero |
|`XXX` |Milliseconds |
|`0XXX` |Milliseconds with leading zero |
|`am` or `pm` |Lower case AM/PM indicator |
|`AM` or `PM` |Upper case AM/PM indicator |
|`TZD` |Timezone offset |
|`\x` |Used to escape a character that would otherwise have special meaning |
|`[UTC]`|Time-shift the represented date to UTC. Must be at very start of format string|

TiddlyWiki\Decimal To Hex

TWCard Numbers Extract
"""
Name = mcr glbl_dec_to_hex5
Tag = `$:/tags/Macro`
"""

```
\define glbl_dec_to_hex5(ur_code)
<$list filter="[[$ur_code$]divide[16]divide[16]divide[16]divide[16]floor[]]" variable=lvl_x4>
<$list filter="[<lvl_x4>multiply[16]multiply[16]multiply[16]multiply[16]]" variable=lvl_d4>
<$list filter="[[$ur_code$]subtract<lvl_d4>divide[16]divide[16]divide[16]floor[]]" variable=lvl_x3>
<$list filter="[<lvl_x3>multiply[16]multiply[16]multiply[16]]" variable=lvl_d3>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>divide[16]divide[16]floor[]]" variable=lvl_x2>
<$list filter="[<lvl_x2>multiply[16]multiply[16]]" variable=lvl_d2>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>divide[16]floor[]]" variable=lvl_x1>
<$list filter="[<lvl_x1>multiply[16]]" variable=lvl_d1>
<$list filter="[[$ur_code$]subtract<lvl_d4>subtract<lvl_d3>subtract<lvl_d2>subtract<lvl_d1>]" variable=lvl_xrem>
<$list filter="[range[15]butfirst[9]match<lvl_x4>add[55]] [range[10]subtract[1]match<lvl_x4>add[48]]" variable=lvl_h4>
<$list filter="[range[15]butfirst[9]match<lvl_x3>add[55]] [range[10]subtract[1]match<lvl_x3>add[48]]" variable=lvl_h3>
<$list filter="[range[15]butfirst[9]match<lvl_x2>add[55]] [range[10]subtract[1]match<lvl_x2>add[48]]" variable=lvl_h2>
<$list filter="[range[15]butfirst[9]match<lvl_x1>add[55]] [range[10]subtract[1]match<lvl_x1>add[48]]" variable=lvl_h1>
<$list filter="[range[15]butfirst[9]match<lvl_xrem>add[55]] [range[10]subtract[1]match<lvl_xrem>add[48]]" variable=lvl_hrem>
<$wikify name=str_hex_out text="0x&#<<lvl_h4>>;-&#<<lvl_h3>>;&#<<lvl_h2>>;&#<<lvl_h1>>;&#<<lvl_hrem>>;" >
<<str_hex_out>>
</$wikify>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
</$list>
\end

TiddlyWiki\Delete All Cards with Tag

TWCard FileSystem AssignVariable
```
<$button>
<$list filter="[tag[ARTICLE]]"><$action-sendmessage $message=tm-delete-tiddler $param=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards with Confirmation
</$button>

<$button>
<$list filter="[tag[ARTICLE]]"><$action-deletetiddler $tiddler=<<currentTiddler>> /></$list>
Del ARTICLE tagged Cards without Confirmation
</$button>

<$button>
<$list filter="[tag[DOC]]" variable=doc_pk><$list filter="[<doc_pk>fields[]prefix[e]]" variable=field_pk2><$action-deletefield $tiddler=<<doc_pk>> $field=<<field_pk2>> /></$list></$list>
Del fields starting with `E` in DOC tagged Cards
</$button>

TiddlyWiki\DivPop btn

TWCard UserAction FileSystem
[[DivPop.svg]]

Tag = `$:/tags/ViewToolbar`

```
\define divpop_current(ur_ref)
<$button class=<<tv-config-toolbar-class>> >
<$action-setfield $tiddler="$:/state/sidebar" text="yes"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text="$ur_ref$"/>
<$action-sendmessage $message="tm-close-tiddler" $param="pop_right"/>
<$list filter="[<tv-config-toolbar-icons>match[yes]]">
{{DivPop.svg}}
</$list>
<$list filter="[<tv-config-toolbar-text>match[yes]]">
<span class="tc-btn-text"><$text text="Popup over Sidebar"/></span>
</$list>
</$button>
\end

<$list filter="[all[current]]">
<$macrocall $name=divpop_current ur_ref=<<currentTiddler>> /> 
</$list>

TiddlyWiki\DivPop glbl

TWCard FileSystem UserAction
Tag = `$:/tags/BelowStory`

```
<$list filter="[{$:/state/popup/DivPopTitle}is[tiddler]]">
<div style="
position: fixed;
top: 0px;
right: 0px;
width: 350px;
border: 3px solid;
background: white;
bottom: 0%;
">
<div style="overflow-y: scroll; height: 100%;">
<$button>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
close
</$button>
<$tiddler tiddler=<<currentTiddler>> >
<$transclude mode="block" />
</$tiddler>
</div>
</div>
</$list>

TiddlyWiki\Embed Font

TWCard Text Formatting FileSystem
"""
[https://tiddlywiki.narkive.com/bS0CgWKQ/tw-tw5-how-to-embed-a-font-using-font-face-and-data-url]
- Visit: http://www.fontsquirrel.com/tools/webfont-generator
- Upload your font file (".ttf", ".eot", ".woff", etc)
- Select option "Expert"
- Check the option case at CSS >> Base64 Encode
- Generate your webkit -> Downloads file

[stylesheet.zip file]
- Unpack ZIP file -> Downloads file

[stylesheet.css]
- Note: The file's content in Base64 encoded

[Wiki file]
- Drag-drop file to import -> Creates Card
- [styleshee.css Card]
- Make sure the field font-family is what you want
- Tag = $:/tags/Stylesheet
- Tiddler type = Plain text (text/plain)
- Create a new Card and use the font

TiddlyWiki\Encrypt file

TWCard FileSystem AssignVariable
"""
[Wiki file]
- [Sidebar, Tools tab]
- Click button Set Password -> Opens dialog
- Password = UrPasswordText
- Repeat password = UrPasswordText
- Click button Set Password -> Closes dialog

[keyboard action SaveAllChanges]
- [<$action-sendmessage $message="tm-download-file"]
- Comment out this tag to keep the HTML Wiki version from being exported
- Save the Wiki file

- Note: The password will be required to start the Wiki application when you open the Wiki file

TiddlyWiki\External Link organization

TWCard FileSystem Formatting
* Create one Card for each external link in this format
** Title always starts with `ext` and a space, then the external link description
** Tagged as EXT
** Contains one line in this format:

```
[ext[ur_url]]
```

* Reference the Card with the `ext` macro, but don't include the `ext` prefix or the leading space
* The link is shown, and there will be `->` on the right side of the Card window
* This flags links that will open in a new tab, and allows you to easily open the `ext` Card and change the saved link

```
<<ext "UrExternalLinkDiscption">>
```

* Global macro
** Title = mcr glbl_ext
** Tag = $:/tags/Macro
** Main Body text =

```
\define ext(ur_extcard_pk)
{{ext $ur_extcard_pk$}}<div style="float:right">[[_|ext $ur_extcard_pk$]]</div>
\end

TiddlyWiki\Filter Operators

TWCard Filter CodeLibrary
!!Math

"""
abs - calculate the absolute value of a list of numbers
add - treating each input title as a number, add to each the numeric value of the operand
ceil - rounds a list of numbers up to the next largest integer
divide - treating each input title as a number, divide them by the numeric value of the operand
exponential - convert each number to exponential notation with N digits
fixed - convert each number to fixed point notation with N digits after the decimal point
floor - rounds a list of numbers to the largest integer less than or equal to each number
max - treating each input title as a number, take the maximum of its value and the numeric value of the operand
maxall - find the largest of a list of numbers
min - treating each input title as a number, take the minimum of its value and the numeric value of the operand
minall - find the smallest of a list of numbers
multiply - treating each input title as a number, multiply it by the numeric value of the operand
negate - calculate the negation of a list of numbers
precision - convert each number to a string with N significant digits
product - produce the product of the input numbers
remainder - treating each input title as a number, return the remainder when divided by the numeric value of the operand
round - rounds a list of numbers to the nearest integer
sign - return -1, 0 or 1 for a list of numbers according to whether each number is negative, zero, or positive
subtract - treating each input title as a number, subtract from each the numeric value of the operand
sum - produce the sum of the input numbers
trunc - truncates a list of numbers to their integer part, removing any fractional part
untrunc - rounds a list of numbers to the next integer with largest absolute value, that is, away from zero

TiddlyWiki\Fonts via URL

TWCard Text Formatting FileSystem
```
<link href='https://fonts.googleapis.com/css?family=Playfair Display' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Sofia' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Alex Brush' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Akronim' rel='stylesheet'>
<link href='https://fonts.googleapis.com/css?family=Annie Use Your Telescope' rel='stylesheet'>

@@font-family: 'Playfair Display';
!'Playfair Display'  1234567890 ABC abc
@@

@@font-family: 'Sofia';
!'Sofia'  1234567890 ABC abc
@@

@@font-family: 'Alex Brush';
!'Alex Brush'  1234567890 ABC abc
@@

@@font-family: 'Akronim';
!'Akronim'  1234567890 ABC abc
@@

@@font-family: 'Annie Use Your Telescope';
!'Annie Use Your Telescope'  1234567890 ABC abc
@@

TiddlyWiki\Global Card Footer

TWCard FileSystem Formatting
Every Card shows the Wikified content of the Card content, followed by the Wikified content of every Card with the tag `$:/tags/ViewTemplate`.

!Example Footer Text

Create a new Card

<<<
template Global Footer
<<<

```
Any Text Here
```

Add the tag:

* $:/tags/ViewTemplate

And then every Card will show the words "Any Text Here" at the bottom of the Card.

!Example Footer Home Button

Create a new Card

<<<
template Home Button
<<<

```
<div style="float:right">{{$:/core/ui/Buttons/home}}</div>
```

Add the tag:

* $:/tags/ViewTemplate

And then every Card will show the "Home" icon at the bottom-right of the Card.



TiddlyWiki\Global Macro

TWCard FileSystem
Tag = `$:/tags/Macro`

TiddlyWiki\Group Totals

TWCard CodeLibrary Filter Numbers
```
unique_groups()
- find list of titles with UrAttribute
    - [has[UrAttribute]]
- split by the prefix before the first hyphen
    - [<currentTiddler>split[-]nth[1]]
- return each title's prefix followed by a space
    - ><<currentTiddler>> <

unique_counts()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces
    - [<ugrp>split[ ]
- ignore white-space only entries, and sort the rest alphabetically
    - !match[]sort[]
- use "each:value" to get the unique title prefixes in the list
    - each:value[]]
- for each unique title prefix, get a count of titles with UrAttribute
    - [has[UrAttribute]prefixcount[]]

count_size()
- create a new variable ugrp with the list of title prefixes from unique_groups()
    - <$wikify name=ugrp text=<<unique_groups>>
- split the new variable by spaces, ignore white-space, sort, use "each:value", store as ur_entry
    - [<ugrp>split[ ]!match[]sort[]each:value[]]
    - ur_entry=<<currentTiddler>>
- for each unique title prefix, only continue where the count of titles with UrAttribute matches the parent unique count
    - [has[UrAttribute]prefix<ur_entry>count[]match[$(currentTiddler)$]]
- find all the titles with the unique title prefix, and return a "1" for each entry
    - [has[UrAttribute]prefix]">1 <

main()
- create a new variable ucnt with the list of title prefixes from unique_counts()
    - <$wikify name=ucnt text=<<unique_counts>>
- split the new variable by spaces, ignore white-space, sort, use "each:value"
    - [split[ ]trim[]!match[]sort[]each:value[]]
- For each unique count,
    - list the entry
    - sum the number of entries returned from count_size() divided by the unique count
```

```
\define unique_groups()
<$list filter="[has[eng-vocab]]"><$list filter="[<currentTiddler>split[-]nth[1]]"><<currentTiddler>> </$list></$list>
\end
\define unique_counts()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]">
<$list filter="[has[eng-vocab]prefix<currentTiddler>count[]]"><<currentTiddler>> </$list>
</$list>
</$wikify>
\end
\define count_size()
<$wikify name=ugrp text=<<unique_groups>> >
<$list filter="[<ugrp>split[ ]!match[]sort[]each:value[]]"><$vars ur_entry=<<currentTiddler>> >
<$list filter="[has[eng-vocab]prefix<ur_entry>count[]match[$(currentTiddler)$]]">
<$list filter="[has[eng-vocab]prefix<ur_entry>]">1 </$list>
</$list>
</$vars></$list>
</$wikify>
\end
<$wikify name=ucnt text=<<unique_counts>> >
<$list filter="[<ucnt>split[ ]trim[]!match[]sort[]each:value[]]">
ASLSJ Prefix Groups with <<currentTiddler>> words -
<$wikify name=usize text=<<count_size>> >
<$list filter="[<usize>split[ ]trim[]!match[]sum[]divide<currentTiddler>]"><<currentTiddler>><br>
</$list>
</$wikify>
</$list>
</$wikify>
```

TiddlyWiki\Hard Line Breaks

TWCard Text Formatting
HTML normally ignores line breaks. TiddlyWiki uses HTML, and includes a way to stop ignoring line breaks.

[TiddlyWiki editor]
- Type three double-quotes (`"""`) and press enter to ignore line breaks below this point
- The (`"""`) does not show up in the output

Three double-quotes will start a hard line breaks section

```
"""
```

```
line one blends into line two continues

"""
line three stops
line four starts
"""
```

line one blends into
line two continues

"""
line three stops
line four starts
"""

!!HTML Preformatted text with Sans-Serif font

`<pre style="font-family: sans-serif;">line three stops
line four starts</pre>`

<pre style="font-family: sans-serif;">line three stops
line four starts</pre>

TiddlyWiki\Hidden on Static File

FileSystem TWCard Formatting
!! Hide section when exported to static HTML file

```
<$list filter="[<tv-config-toolbar-icons>match[no]]">
```

TiddlyWiki\iFrame

TWCard HTMLCode FileSystem Extract
Use an iFrame to run JavaScript in a TiddlyWiki

```
>iframe src="javascript:newWindow='';var ...
```

- just `javascript:newWindow=var ...` did not compile. An empty string is a work-around.

Alternative output: use alert instead of document.write

```
alert(strTEXT);"/>
```

How to reference an external HTML file in a tiddler

```
>iframe src=...  scrolling=yes style="border-style:none;height:100%;width:100%">
>/iframe>
```

- A self-closing tag does not allow remaining html code to be displayed
- ALWAYS specify a closing >/iframe> tag

TW Macro to show iframe and link

```
>div style='float:right'>[ext[_ |$ur_pk$.txt.html]]
>/div>
>iframe src='$ur_pk$.txt.html'>
>/iframe>
```

- $macrocall $name=iframe_txt ur_pk= currentTiddler

```
<iframe src="javascript:newWindow='';var qs = '&quot;';var qt = '&apos;';

var objFRAME = document.createElement('iframe');
objFRAME.setAttribute('id', 'innerFrame');
objFRAME.setAttribute('src', 'http://www.google.com/');
document.body.appendChild(objFRAME); 
var objTEST = objFRAME;
var strTEXT = '';
if (objTEST===undefined) {
strTEXT = 'undef obj';
} else if (objTEST===null) {
strTEXT = 'null obj';
} else {
var intSEQ = 0;
var strNAME;
for (strNAME in objTEST) {
intSEQ += 1;
strTEXT += ' ; ' + strNAME;
}
strTEXT = 'olen ' + intSEQ + strTEXT;
}
document.write(strTEXT);"></iframe>

alert(strTEXT);"/>

<iframe src='iframe.scrE2.txt' height=100% width=100% scrolling=yes frameborder=no></iframe>


\define iframe_txt(ur_pk)
<div style="float:right">[ext[_ |$ur_pk$.txt.html]]</div>
<iframe src='$ur_pk$.txt.html' scrolling=yes style="border-style:none;height:100%;width:100%"></iframe>
\end

TiddlyWiki\Ignore WikiText formatting

TWCard Text Formatting
!! Use the TextWidget to ignore WikiText formatting

* widget name = `$text`
* `text` attr = <$text text="`still black colored text`" />

!! Sample code

```
<$text text="`still black colored text`" />
```

<<<
Results:

<$text text="`still black colored text`" />
<<<
!! Use the Rules card pragma to ignore WikiText formatting

* [New card]
* Put `\rules only` at the top of the card text

!! Sample code

```
\rules only
`still black colored text`
```

<<<
Results:

<$text text="`still black colored text`" />
<<<

!! Use the Card Datatype to ignore WikiText formatting

* [New card]
* `type` field = `text/plain`

!! Sample code

```
`still black colored text`
```

<<<
Results:

```
`still black colored text`
```
<<<

TiddlyWiki\Image

TWCard Formatting
"""
Link an image in a Tiddler with 500px width
- Have image tiddler
- Have text tiddler
- Apply image to text tiddler at 500px width

[New tiddler]
- title = mcr img_link
- tag = $:/tags/Macro
- text field code
"""

```
\define img_link(ur_pk)
@@max-width:500px;
[img [$ur_pk$]]
@@
\end
```

"""
[Text tiddler]
- $macrocall $name=img_link ur_pk= currentTiddler
"""

TiddlyWiki\Image link opens Card

TWCard UserAction FileSystem
Tag = `$:/tags/Macro`

```
\define glbl_image_high(ur_image_pk, ur_size:200)
<$link to="$ur_image_pk$">[img height=$ur_size$px [$ur_image_pk$]]</$link>
\end
\define glbl_image_wide(ur_image_pk, ur_size:500)
<$link to="$ur_image_pk$">[img width=$ur_size$px [$ur_image_pk$]]</$link>
\end

TiddlyWiki\Import Macros

TWCard FileSystem
```
\import [[mcr date_list]]

TiddlyWiki\Javascript Calculation in Bookmarklet

TWCard Bookmarklet Extract JavaScriptCode
* Click the button to copy the text to a javascript bookmarklet
* Open a new tab
* Type the letter "j" in the address bar, paste in the clipboard text, and press enter
* The Javascript alert box shows the message

```
\define glbl_copyto_js_bookmarklet(ur_js_code)
<pre>$ur_js_code$</pre>
<$macrocall $name="copy-to-clipboard" src="""avascript:newWindow=window.open("about:blank","newWindow");if(window.focus){const el = newWindow.document.createElement('textarea');const ur_str='$ur_js_code$';try {el.value =eval(ur_str)}catch(err) {el.value = err.message;}; newWindow.document.body.appendChild(el); el.select();void(newWindow.focus());}""" />
\end

<!--|v
<<glbl_copyto_js_bookmarklet """parseInt("FF",16).toString(10);""">>
^|-->

TiddlyWiki\Keep words together on one line

TWCard Text Formatting
!! Use CSS white-space tag

* The CSS `white-space:nowrap;` disables normal text wrapping
* This is useful when you have several smaller phrases that should not be separated visually onto different lines
* Note: This can make the line extend past the edge of the browser window, requiring scrolling to see the rest

!!Sample Code that can split phrases

```
A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)
```

<<<
Results:

A code line (1) A code line (2) A code line (3) A code line (4) A code line (5) A code line (6) A code line (7) A code line (8) A code line (9) A code line (10) A code line (11) A code line (12) A code line (13) A code line (14)
<<<

!!Sample Code that can keeps short phrases together

```
@@white-space:nowrap;A code line (1)@@ @@white-space:nowrap;A code line (2)@@ @@white-space:nowrap;A code line (3)@@ @@white-space:nowrap;A code line (4)@@ @@white-space:nowrap;A code line (5)@@ @@white-space:nowrap;A code line (6)@@ @@white-space:nowrap;A code line (7)@@ @@white-space:nowrap;A code line (8)@@ @@white-space:nowrap;A code line (9)@@ @@white-space:nowrap;A code line (10)@@ @@white-space:nowrap;A code line (11)@@ @@white-space:nowrap;A code line (12)@@ @@white-space:nowrap;A code line (13)@@ @@white-space:nowrap;A code line (14)@@
```

<<<
Results:

@@white-space:nowrap;A code line (1)@@ @@white-space:nowrap;A code line (2)@@ @@white-space:nowrap;A code line (3)@@ @@white-space:nowrap;A code line (4)@@ @@white-space:nowrap;A code line (5)@@ @@white-space:nowrap;A code line (6)@@ @@white-space:nowrap;A code line (7)@@ @@white-space:nowrap;A code line (8)@@ @@white-space:nowrap;A code line (9)@@ @@white-space:nowrap;A code line (10)@@ @@white-space:nowrap;A code line (11)@@ @@white-space:nowrap;A code line (12)@@ @@white-space:nowrap;A code line (13)@@ @@white-space:nowrap;A code line (14)@@
<<<

TiddlyWiki\Keyboard Shortcut

TWCard CodeLibrary UserAction
!!Pre-requisites

* You need a `ur_message_to_send` to replace in the below steps
** `tm-home` is an example message that TiddlyWiki can do
* You need a `ur_card_pk` to replace in the below steps
** It should describe the desired action

!!Setup keyboard shortcut

[New Card]

* Title = $:/config/ShortcutInfo/ur_card_pk
* Main Body text is blank

[New Card]

* Title = $:/config/shortcuts/ur_card_pk
* Main Body Text =

```
alt-H
```

[New Card]

* Title = keyboard action ur_card_pk
* Tag = $:/tags/KeyboardShortcut
* Field-Value: key =

```
((ur_card_pk))
```

* Main Body Text =

```
<$action-sendmessage $message="ur_message_to_send"/>
```

TiddlyWiki\List Links from Numbered Fields

TWCard Filter Numbers
```
<ol>
<$list filter="[<currentTiddler>fields[]prefix[e]sort[]]" variable=lookup_name>
<$list filter="[<currentTiddler>get<lookup_name>]" variable=ref_card_pk>
<$list filter="[<ref_card_pk>get[img]else[]]" variable=ref_img_pk>
<li><$link to=<<ref_card_pk>> />@@float: right;overflow: auto;vertical-align: top;padding-left: 10px;<$image width=200px source=<<ref_img_pk>> />@@<div style="clear:both;"></div></li>
</$list>
</$list>
</$list>
</ol>

TiddlyWiki\List Links of Prefixed Cards

TWCard Filter
```
<ol>
<$list filter="[<currentTiddler>addsuffix[\]]">
<$list filter="[all[tiddlers]prefix<currentTiddler>sort[]]">
<li><$link to=<<currentTiddler>> /></li>
</$list>
</$list>
</ol>

TiddlyWiki\List Links standard

TWCard Filter
```
<<list-links filter:"[tag[DOC]field:level[1]sort[title]] [tag[DOC]field:level[]sort[title]]">>

TiddlyWiki\List Widget

TWCard Filter
! Content and Attributes

The content of the `<$list>` widget is an optional template to use for rendering each tiddler in the list.

The action of the list widget depends on the results of the filter combined with several options for specifying the template:

* If the filter evaluates to an empty list, the text of the ''emptyMessage'' attribute is rendered, and all other templates are ignored
* Otherwise, if the ''template'' attribute is specified then it is taken as the title of a tiddler to use as a template for rendering each item of the list
* Otherwise, if the list widget content is not blank, it is used as a template for rendering each item of the list
* Otherwise, a default template is used consisting of a `<span>` or `<div>` element wrapped around a link to the item

|!Attribute |!Description |
|filter |The [[tiddler filter|Filters]] to display |
|template |The title of a template tiddler for transcluding each tiddler in the list. When no template is specified, the body of the ListWidget serves as the item template. With no body, a simple link to the tiddler is returned. |
|editTemplate |An alternative template to use for [[DraftTiddlers|DraftMechanism]] in edit mode |
|variable |The name for a [[variable|Variables]] in which the title of each listed tiddler is stored. Defaults to ''currentTiddler'' |
|emptyMessage |Message to be displayed when the list is empty |
|storyview |Optional name of module responsible for animating/processing the list |
|history |The title of the tiddler containing the navigation history |

!! Additional Notes and Edge Cases

* If the `filter` attribute is not present then a default of `[!is[system]sort[title]]` is used
* If the list widget is completely empty (ie only whitespace between the opening and closing tags), then it behaves as if the content were a `DIV` or a `SPAN` containing a link to the current tiddler (it’s a `DIV` if the list widget is in block mode, or a SPAN if it is in inline mode)
* If the `template` attribute is not present then the content of the list widget will be used as the template, unless the widget is completely empty in which case a default template is used

TiddlyWiki\Local Video or Audio Files

TWCard Video Audio FileSystem CodeLibrary
```
<video width="320" height="180"
poster="video\Frozen Sleep - Cortana Tribute by Malukah.png"
controls preload="none">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.webm" type=
"video/webm">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.ogv" type=
"video/ogg">
<source src="video\Frozen Sleep - Cortana Tribute by Malukah.mp4" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
```

```
<audio controls preload="none">
<source src="audio\Frozen-Sleep-Malukah.ogg" type="audio/ogg">
<source src="audio\Frozen-Sleep-Malukah.mp3" type="audio/mp3">
<p>Your browser does not support the HTML 5 audio tag.</p>
</audio>
```

TiddlyWiki\Pagination

TWCard Text Formatting Filter
```
\define page_next()
<$list variable="filter_prev_page" filter="[<page_pk>get[text]!match[0]!match[]]">
<$button style="margin-left:30px">
<$action-setfield $tiddler=<<page_pk>> text=""/>
First page
</$button>

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>subtract[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/></$list>
Previous page
</$button>
</$list><!--filter_prev_page-->

<$button style="margin-left:30px">
<$list variable="next_page" filter="[<cur_page_skip>add[10]]"><$action-setfield $tiddler=<<page_pk>> text=<<next_page>>/><$action-navigate $to=<<card_pk>> $scroll="yes"/></$list>
Next page
</$button><br>
<!--***page_next***-->
\end
<$list variable="card_pk" filter="[<currentTiddler>]">
<$list variable="popup_pk" filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]">

<$list variable="page_pk" filter="[<popup_pk>addsuffix[-cur_page]]">
<$list variable="cur_page_skip" filter="[<page_pk>get[text]!match[]else[0]]">
<$list variable="cur_page_num"filter="[<cur_page_skip>add[1]]">
<$list variable="cur_page_through" filter="[<cur_page_num>subtract[1]add[10]]">
<<page_next>>

<$list variable="subdir_count" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]count[]]">

Subdirectories <<cur_page_num>> through <<cur_page_through>>

Number of subdirectories: <<subdir_count>><br>
<$list variable="cur_subdir_path" filter="[{File List Data}splitregexp[\n]!suffix[.JPG]!suffix[.jpg]butfirst<cur_page_num>first[10]]">

<$list variable="raw_image_count" filter="[{File List Data}splitregexp[\n]prefix<cur_subdir_path>uppercase[]suffix[.JPG]count[]addprefix[ (]addprefix<cur_subdir_name>addsuffix[ photo]]">
<<raw_image_count>>
</$list><!--raw_image_count-->

</$list><!--cur_subdir_path-->
</$list><!--subdir_count-->
<<page_next>>
</$list><!--cur_page_through-->
</$list><!--cur_page_num-->
</$list><!--page_pk-->
</$list><!--popup_pk-->
</$list><!--card_pk-->

TiddlyWiki\Popup State Clear All

TWCard CodeLibrary AssignVariable
```
<$list filter="[<currentTiddler>removeprefix[Draft of ']removesuffix[']addprefix[$:/state/]] [<currentTiddler>!prefix[Draft of ']addprefix[$:/state/]]" variable="popup_pk">
<$button>
<$list filter="[all[tiddlers]prefix<popup_pk>has[text]]" variable=del_pk><$action-deletefield $tiddler=<<del_pk>> $field="text"/></$list>
Show All
</$button><br>

</$list>

TiddlyWiki\Published Tools

TWCard CodeLibrary
https://dynalist.io/d/zUP-nIWu2FFoXH-oM7L7d9DM#z=zdF80rIaJ79W5P0IGsjYIjkD

"""
[Ace editor](http://innoq.tiddlyspot.com/)
[ActionIncrement widget](https://skeeve.github.io/tw5-plugins/) - The action-increment widget is an action widget that retrieves a value from a text reference. It will then increase the first digit-sequence found in that text and store it.
[Ad-Hoc Macro](https://tobibeer.github.io/tb5/#Ad-Hoc%20Macro) - evaluate any text as an ad-hoc macro even passing variables.
[Amazon Web Services Plugin](https://tiddlywiki.com/#OfficialPlugins) - provides several tools for working with Amazon Web Services **(official TW plugin)**
[Delay Actions](https://groups.google.com/forum/#!topic/tiddlywiki/z7SGLAPODW8), defer the execution of action widgets for a set amount of time
[CouchDB adaptor](https://github.com/wshallum/couchadaptor)
[Count (tobibeer)](http://tobibeer.github.io/tw5-plugins/#count) - A filter to count titles or compare against a specified count
[Demo Code Macro](http://ooktech.com/jed/ExampleWikis/DemoCodeMacro/) - This is an attempt to make a macro that can be used to demonstrate wikitext code fragments in an interactive way.
[dom (tobibeer)](http://tobibeer.github.io/tw5-plugins/#dom) - retrieve text or attributes from dom nodes
[eval (tobibeer)](http://tobibeer.github.io/tw5-plugins/#eval) - Evaluate expressions, compute and compare tiddler properties and data
[Fargo.io integration](http://blog.jeffreykishner.com/2014/01/24/note-taking-bookmarklets-for-fargoio-and-tiddlywiki-.html)
[Global macros, instructions on how to make](http://tw5magick.tiddlyspot.com/)
[Highlight plugin](https://tiddlywiki.com/plugins/tiddlywiki/highlight/#%24%3A%2Fplugins%2Ftiddlywiki%2Fhighlight) **(official TW plugin)** - description: Plugin that activates syntax highlighting of code blocks using v8.8.0 of highlight.js from Ivan Sagalaev. demo [here](https://tiddlywiki.com/plugins/tiddlywiki/highlight/)
[HTAlink](http://welford.github.io/) - Will only work in offline hta editions of this page. Launches external links in your default browser and not IE
[ifAisB](https://tid.li/tw5/hacks.html) - This macro allows to test if a value A – a variable or a transcluded value – matches a value B and to react accordingly. It works almost like an if-then-else statement.
[IfTid Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the existence of a tiddler (or field) and to send different widget messages based upon the existence of this tiddler (or field.) 
[IfTref Widget](http://gwiz.tiddlyspot.com/) - need to change tw- to tc-. The widget is used to test for the value of a TextReference and to send different widget messages based upon whether this value matches the value specified by the 'value=' attribute.
[Incremental load command](http://malsandbox.tiddlyspot.com/) - only loads tiddlers that either don't already exist in the tiddlers folder, or have a newer modified date than the existing tiddler.
[Javascript macros in wikitext](http://tw5magick.tiddlyspot.com/)
[JSON editor (btheado)](http://btheado.github.io/jsoneditor.html)
[JSON editor (bjtools)](http://bjtools.tiddlyspot.com/)
[JsonMangler](https://joshuafontany.github.io/TW5-JsonMangler/) - This plugin changes the methods tiddlywiki uses to retrieve and set values in json data tiddlers. It does this in a way that aims for backwards compatibility.

[keyboard-snippets plugin](http://braintest.tiddlyspot.com/#keyboard-snippets)
[LetWidget](http://tiddlystuff.tiddlyspot.com/) - The LetWidget is an enhancement of the SetWidget.
[mforth](https://quaraman.de/tw/mforth.html) - It is a forth like language in a tiddlywiki macro. Forth operates with Reverse Polish Notation (RPN for short).
[Mousetrap](http://welford.github.io/) - simple library for handling keyboard shortcuts in Javascript.
[muut integration](http://ooktech.com/jed/ExampleWikis/TiddlyWiki-muut/)
[Nodewebkitsaver plugin](http://ooktech.com/jed/ExampleWikis/SetFilters/#%24%3A%2Fplugins%2FOokTech%2FSetFilters) - provides a saver module for saving changes when using [TiddlyWiki](http://ooktech.com/jed/ExampleWikis/SetFilters/#TiddlyWiki) directly under NW.js (previously known as node-webkit).
[Pack as plugin](http://braintest.tiddlyspot.com/#Pack%20as%20plugin) - Beta version
[Pan widget](http://muritest.tiddlyspot.com) - This widget is touch sensitive. It is able to trigger actions as the start and end of pans. Multiple differntial pans are possible.
[Persistent-states](https://wikilabs.github.io/#persistent-states) and [Remove-states](https://wikilabs.github.io/#remove-states)
[pick Plugin](https://skeeve.github.io/tw5-plugins/) - The pick plugin is a set of two filters and one widget to help extracting data from your TiddlyWiki file.
[PluginSize](https://tid.li/tw5/plugins.html#%24%3A%2Fplugins%2Ftelmiger%2FPluginSize:%24%3A%2Fplugins%2Ftelmiger%2FPluginSize) - This plugin calculates the size of all installed plugins, including themes and languages.
[PluginDevelopment](https://github.com/inmysocks/PluginDevelopment) -- Scripts to help you create plugins and plugin libraries for node.js
[pv5](http://pv5.tiddlyspot.com/) - testing params and variables
[random (tobibeer)](http://tobibeer.github.io/tw5-plugins/#random) - A filter to return one or more random titles
[ReplacePragma](http://tiddlystuff.tiddlyspot.com/)
[Save trail plugin](https://tiddlywiki.com/#OfficialPlugins) - This plugin causes TiddlyWiki to continuously download (as a JSON file) the contents of any tiddler that is manually changed by any of several means **(official TW plugin)**
[setvars (tobibeer)](http://tobibeer.github.io/tw5-plugins/#setvars) - Set multiple, complex variables based on attributes, filters, or conditionals
[Shuffle filter operator](https://mklauber.github.io/tw5-plugins/#Shuffle%20Operator) - implements a new filter operator called Shuffle. This operator takes the input list and randomizes the order of the list. If no parameter is provided, the list order is random every time.
[SPilot4Tw](https://www.quaraman.de/tw/pilot.html) - A programming language that can be included as Tiddlywiki plugin.
[Startup Actions demo](http://ooktech.com/jed/ExampleWikis/StartupActions/) - A plugin to add startup scripts to TiddlyWiki 
[style (tobibeer)](http://tobibeer.github.io/tw/style/#GettingStarted) - This wiki introduces you to using your desktop browser to inspect the styles applied to elements in TiddlyWiki and permanently change them.
[Three.js](http://rboue.tiddlyspot.com/#Three.js%2Fintroduction) - 3D modeling
[TiddlyWiki5 Coding](http://cjhunt.github.io/) - These pages document aspects TiddlyWiki5 programming, sharing "lessons learned" to help developers to get started with TiddlyWiki5 customization and extension. (FYI - 4 years old)
[Tinka](https://tinkaplugin.github.io/) - Create and modify plugins in the browser. 
[Trace-variable example](http://eucaly-tw5.tiddlyspot.com/#trace-variable%20Example) - no clue what this is.
[Trigger Actions Demo](http://ooktech.com/jed/ExampleWikis/TriggerActions/)
[Tutorial Maker with HopScotchjs](https://cdn.rawgit.com/abesamma/TW5-tutorial-maker-plugin/29c31124/Demo.html) - a plugin that allows TW5 developers to create interactive product tutorials for their tiddlywiki projects, to guide new users.
[TW Components](https://tw-scripts.github.io/TW-Components/) - A component is a group of TW macros and tiddlers create a visual element for complex processes. The ultimate objective of TW components is to create objects which can simply by used by TW programmer to create complex plugins or codes.
[twexe - run exe's from hta files](https://github.com/welford/twexe) - only works in offline hta versions of TW. It lets you register and run exes from tiddlywiki

TiddlyWiki\Recently Changed Cards

TWCard CodeLibrary Filter
```
<<timeline limit:30 format:"YYYY-0MM-0DD">>

TiddlyWiki\Regular Expression

TWCard Text Filter
```
<!--|v
Split at Regular Expression skips everything before the first period -> `.12`,  `.1` and `.or.maybe.1`
^|-->

<$vars re="^[^\.]*">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>

<!--|v
Split at Regular Expression skips everything before the last period -> `1`,  `1` and `1`

Each:Value gets the unique list of entries -> `2` and `1`

Sort orders them numberically
^|-->

<$vars re="^.*\.">
<$list variable="found_section" filter="[[no.12]] [[no.100]] [[yes.or.maybe.100]] +[splitregexp<re>!match[]each:value[]sortan[]]">
<<found_section>>
</$list><!--found_section-->
</$vars>


<!--|v
Split
^|-->

<!--<$vars re="^[^\.]*"> skip up to first period excluded-->
<!--<$vars re="^.*\."> skip up to first period included-->
<$vars card_pk="File List Data" re="^.*\.">
<$list variable="cur_file_ext" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.gif(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.jpeg(?i)]] [<card_pk>get[text]splitregexp[\n]regexp[\.jpg$(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.png(?i)]] [<card_pk>get[text]splitregexp[\n]splitregexp[\n]regexp[\.tif(?i)]] +[splitregexp<re>!match[]each:value[]sort[]addprefix[.]]">
<$list variable="file_ext_count" filter="[<card_pk>get[text]splitregexp[\n]splitregexp[\n]suffix<cur_file_ext>count[]]">

<<cur_file_ext>>: <<file_ext_count>> files
</$list><!--file_ext_count-->
</$list><!--cur_file_ext-->
</$vars>

TiddlyWiki\Reveal Section and Copy Data

TWCard Text Formatting AssignVariable
Title = mcr T1Reveal

```
\define t1cb(UrContent)
<$list filter="[[$UrContent$]!match[]]">
$UrContent$
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
\end
\define t1reveal(UrPK UrSeq UrContent)
<$list filter="[[$UrContent$]!match[]]">
<br>
<$reveal type="nomatch" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="show">,,$UrSeq$,,</$button>
</$reveal>
<$reveal type="match" state="$:/state/popup/$UrPK$\$UrSeq$" text="show">
<$button set="$:/state/popup/$UrPK$\$UrSeq$" setTo="hide">^^$UrSeq$^^</$button><br>
"""
$UrContent$
"""
</$reveal>
<$list filter="[[$UrSeq$]match[Pwd]]">
<$button message="tm-copy-to-clipboard" param="$UrContent$">
Copy to clipboard
</$button>
</$list>
</$list>
\end

TiddlyWiki\Save Wiki and Export HTML

TWCard CodeLibrary Extract Browser
```
\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/tab/sidebar--595412856" text="$:/core/ui/SideBar/More"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.htm"
/>
<$action-sendmessage $message="tm-download-file"
$param="$:/core/templates/exporters/StaticRiver" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
exportFilter="""[all[tiddlers]tag[INDEX]sort[title]][all[tiddlers]!tag[EXTLINK]!tag[INDEX]!tag[META]!prefix[Draft of]!is[image]!is[tag]!is[system]sort[title]]"""/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.htm]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>

TiddlyWiki\Search all Fields

TWCard Text Filter
```
<$vars search_text_pk="$:/state/popup/SearchAllFields">
<$list variable=show_code_pk filter="[<search_text_pk>addsuffix[-checkShowCode]]">
<$list variable=skip_system_pk filter="[<search_text_pk>addsuffix[-checkSkipSystem]]">
<$edit-text tiddler=<<search_text_pk>> field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
<$checkbox default="no" unchecked="no" checked="yes" field="text" tiddler=<<show_code_pk>>> Show Code</$checkbox>
<$checkbox default="yes" unchecked="no" checked="yes" field="text" tiddler=<<skip_system_pk>>> Skip System </$checkbox><br>
<br>

<$list variable=cur_search_text filter="[<search_text_pk>get[text]addsuffix[(?i)]!match[]]">
<$list variable=cur_showcode_text filter="[<show_code_pk>get[text]else[no]]">
<$list variable=cur_skipsystem_text filter="[<skip_system_pk>get[text]else[yes]match[yes]count[]]">

<!--Card titles-->
<$list variable=cur_pk filter="[regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_skipsystem_text>] [<cur_pk>!is[system]count[]] +[sum[]match[1]]">

<$link to=<<cur_pk>> />: title
</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

<!--Card fields-->
<$list variable=cur_pk filter="[!regexp<cur_search_text>sort[]]">
<$list variable=found_skipsystem filter="[<cur_pk>is[system]count[]multiply<cur_skipsystem_text>match[0]]">
<$list variable=cur_field filter="[<cur_pk>fields[]]">
<$list variable=found_field filter="[<cur_pk>get<cur_field>regexp<cur_search_text>]">

<$link to=<<cur_pk>> />: <<cur_field>>
<$list variable=disp_code filter="[<cur_showcode_text>match[yes]]">
<$codeblock code=<<found_field>> />
</$list><!--disp_code-->
</$list><!--found_field-->
</$list><!--cur_field-->

</$list><!--found_skipsystem-->
</$list><!--cur_pk-->

</$list><!--cur_skipsystem_text-->
</$list><!--cur_showcode_text-->
</$list><!--cur_search_text-->
</$list><!--skip_system_pk-->
</$list><!--show_code_pk-->
</$vars><!--search_text_pk-->

TiddlyWiki\Section Display

TWCard Text Formatting
Card name = `mcr glbl_section_disp`

Tag = `$:/tags/Macro`

```
\define glbl_section_disp(ur_title, ur_section_num)
<$reveal type="nomatch" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="show">

!!$ur_title$ - Show
</$button></$reveal>
<$reveal type="match" state="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" text="show">
<$button class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">

!!$ur_title$
</$button><br>

<<section$ur_section_num$>>

<$button style="float:right" class="tc-btn-invisible" set="$:/state/popup/$(currentTiddler)$-popup$ur_section_num$" setTo="hide">
---
</$button><br>
</$reveal>
\end
<!--|v
-- Card content call

\define section1()

section content

!!!here

\end
<<glbl_section_disp "Section 1" 1>>
^|-->

TiddlyWiki\Source Code Samples

TWCard CodeLibrary
!!TiddlyWiki Git repository sample code

[Home button]
<<ext "Tiddly Wiki Home Button source code">>

```
{{$:/core/images/home-button}}
```

<<<
{{$:/core/images/home-button}}
<<<


[Save button]
<<ext "TiddlyWiki Save Button source code">>

```
<$action-sendmessage $message="tm-save-wiki" $param={{$:/config/SaveWikiButton/Template}} filename=<<site-title>>/>
```

* This code says I can specify my own download file name

```
<span class="tc-dirty-indicator">
```

* This code changes the color of elements within the `<span>` to red when the Wiki file has not been saved

[TiddlyWiki TopBar Menu]

<<ext "TiddlyWiki TopBar Menu">>

```
<$button set="$:/state/sidebar" setTo="no"/>
<$button set="$:/state/sidebar" setTo="yes"/>
```

* These lines show that the `$:/state/sidebar` Card is "no" to hide the sidebar, or "yes" show it

TiddlyWiki\Split Lines into Storage

TWCard Text AssignVariable
```
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>fields:exclude[created title modified]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<new_line_pk>> $field=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:25px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Temp Table

TWCard CodeLibrary AssignVariable
```
\define ui(ur_pk)
<$wikify name=lf_char text="&#x000A;">
<$list
variable=ttbLINE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbLINE]]""">
<$list
variable=ttbPAGE filter="""[[$(currentTiddler)$]split[Draft of ]join[]split[']join[]addprefix[$:/state/popup/]addsuffix[-ttbPAGE]]""">
<$list
variable=dest_count filter="""[prefix<ttbLINE>indexes[]count[]]""">
<$list
variable=rec_count filter="""[[$ur_pk$]get[text]splitregexp[\n]count[]]""">
<$list
variable=rem_count filter="""[<ttbPAGE>get[text]splitregexp[\n]count[]divide[100]trunc[]add[1]]""">
<$list
variable=cur_pagek filter="""[<ttbPAGE>get[pagek_seq]else[0]]""">

Rem page count: <<rem_count>> | Current page: <<cur_pagek>> | <$link to=<<ttbPAGE>> /><br>


<$list
variable="display_snapshot_button" filter="[<ttbPAGE>get[text]else[]!match[]]">

<$list
variable="display_split_button" filter="[<rem_count>!match[0]]">
<$button>

<$list
variable=new_line_pk filter="""[<ttbLINE>addsuffix[-]addsuffix<cur_pagek>]""">
<$list
variable=cur_seq filter="""[range[100]subtract[1]]""">
<$list
variable=new_row_seq filter="""[<cur_pagek>subtract[1]multiply[100]add<cur_seq>add[1]]""">
<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst<cur_seq>first[]]""">
<$action-setfield $tiddler=<<ttbLINE>> $index=<<new_row_seq>> $value=<<rec_line>>/>
</$list><!--rec_line-->
</$list><!--new_row_seq-->
</$list><!--cur_seq-->
</$list><!--new_line_pk-->

<$list
variable=rec_line filter="""[<ttbPAGE>get[text]splitregexp[\n]butfirst[100]join<lf_char>]""">
<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value=<<rec_line>>/>
</$list><!--rec_line-->

<$list
variable="next_page" filter="[<ttbPAGE>get[pagek_seq]add[1]]"><$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value=<<next_page>>/></$list><!--next_page-->

Split Chars
</$button></$list><!--display_split_button--></$list><!--display_snapshot_button--><$button
style="margin-left:200px">

<$list
variable=del_line_pk filter="""[prefix<ttbLINE>]"""><$action-sendmessage $message=tm-delete-tiddler $param=<<del_line_pk>> />
</$list><!--del_line_pk-->

<$action-setfield $tiddler=<<ttbPAGE>> $field="pagek_seq" $value="1"/>

<$action-setfield $tiddler=<<ttbPAGE>> $field="text" $value={{$ur_pk$}}/>

Clear Chars
</$button>

<$link to=<<ttbLINE>> />
<$list
variable=found_line_pk filter="""[prefix<ttbLINE>]""">
<$list
variable=disp_line_pk filter="""[<found_line_pk>removeprefix<ttbLINE>removeprefix[-]]""">
<$link to=<<found_line_pk>> ><<disp_line_pk>></$link>
</$list><!--disp_line_pk-->
</$list><!--found_line_pk-->

Source line count: <<rec_count>><br>

Dest field count: <<dest_count>>

</$list><!--cur_pagek-->
</$list><!--rem_count-->
</$list><!--rec_count-->
</$list><!--dest_count-->
</$list><!--ttbPAGE-->
</$list><!--ttbLINE-->
</$wikify><!--lf_char-->
\end

<<ui "UrPK">>

TiddlyWiki\Text Differences

TWCard Text Extract
```
<$diff-text source={{FirstTiddler}} dest={{SecondTiddler}}/>

TiddlyWiki\Textbox field

TWCard AssignVariable
\define sample_data_e1()
<$edit-text tiddler="$:/state/popup/TestText1" field=text default="" placeholder="[no text yet]" autoHeight=yes tag=input/>
\end

\define sample_data_e2()
<$edit-text tiddler="$:/state/popup/TestText2" field=text default="here" placeholder="[no text yet]" autoHeight=yes tag=textarea/>
\end

You can choose to edit a Card or a Card's field in a single-line or multi-line textbox.

* The `default` parameter is automatically placed in the textbox when the Card does not exist
** Typing in the box will add to the default text
** The Card will be created when the text in the box is changed
** Otherwise the default text will not be saved

* The `placeholder` parameter is shown as greyed-out text when the Card does not exist and there is no default text, or the Card exists and the text field is empty
** Typing in the box will overwrite the placeholder text

Note: Editing a Card PK that starts with `$:/state/popup/` will not be saved and does not affect the Wiki's "dirty" flag

[[$:/state/popup/TestText1]]
<$codeblock code=<<sample_data_e1>> />
<<sample_data_e1>>

---
[[$:/state/popup/TestText2]]
<$codeblock code=<<sample_data_e2>> />
<<sample_data_e2>>

TiddlyWiki\TiddlySaver from Downloads

TWCard FileSystem WindowsOS
Make a small form with a timer that moves downloaded TiddlyWiki files back to their original folder

- I have not tried to play around with running TW5 on Node.js. I don't prefer having to use TiddlyDesktop as a separate web browser. Installing a plugin would only save my wiki changes under the downloads directory. I like using a portable web browser on my thumb drive, and I am able to run non-admin programs on my computer. So I made a small program with a timer to move each saved TW file from my Downloads directory back to its original loading location.

- I leave the program running all the time I am logged in. Alt-S saves the data in TiddlyWiki to the Downloads folder. After at most five seconds, the timer moves the file to overwrite the original location. The form flashes on the screen for one second and then hides itself until another move.

1) I created an alt-S shortcut macro to save the current wiki with a specific filename prefix (TWMove_), the entire file path - with substitutions for path-specific characters (: and \), and a time stamp. (Using split/join is accurate enough for me.)

Example: TWMove_C-colon-slash-RootDirOne-slash-SubDirTwo-slash-UrWiki.html

```

\define ExportSaveAll(ur_filename ur_stamp)
<$action-setfield $tiddler="$:/state/popup/DivPopTitle" text=""/>
<$action-setfield $tiddler="$:/state/sidebar" text="no"/>
<$action-sendmessage $message="tm-save-wiki" filename="TWMove_$ur_filename$-stamp-$ur_stamp$.html"
/>
\end
<$list filter="[{$:/info/url/full}split[file:///]join[]split[:]join[-colon-]split[.html]join[]split[%20]join[ ]split[/]join[-fslash-]split[%]join[-percent-]]">
<$macrocall $name="ExportSaveAll" ur_filename=<<currentTiddler>> ur_stamp=<<now format:"YYYYm0MMd0DDam0hhm0mms0ss">> />
</$list>
```

2) I have my web browser save all downloaded files to a specific Downloads folder. (Specifically on Google Chrome, I did install a plugin to automatically hide the dowloaded files bar. It was getting annoying.)

3) I created a small program with a multi-line textbox, and a timer to poll the Downloads folder every five seconds. It moves all the TWMove files in alphabetical order, so the latest timestamped file will be processed last. It finds the destination path as part of the filename. (Moving assumes the original TW.html file is not locked by the browser. This happened to me once, but I just had to restart the browser to release the file lock.)

The program's text box shows the folder I'm polling. When it picks up a file, the original path is pre-pended to the textbox's list of processed files and the form flashes in the foreground for a second. (I could have made a system tray pop-up notification instead.)

It's not perfect, but definitely doable for most amateur programmers.

TiddlyWiki\Transclude Card Field

TWCard Text Extract
```
<$transclude mode="block" tiddler=<<currentTiddler>> />

<$transclude mode="inline" tiddler=<<currentTiddler>> field="ref_data" />

TiddlyWiki\Unicode Character List

TWCard Unicode CodeLibrary
```
\define CharRef(ur_code, ur_line_grouping)
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]floor[]] " variable=div_val>
<$list filter="[[$ur_code$]divide[$ur_line_grouping$]match<div_val>] "><br><sub>$ur_code$
<<glbl_dec_to_hex5 "$ur_code$">>
</sub><br>
</$list>
</$list>
[&#$ur_code$;]
\end

https://en.wikipedia.org/wiki/Unicode_block

https://en.wikipedia.org/wiki/Plane_(Unicode)


<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text=""/>
Line Grouping = 10
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef LineGrouping" text="16"/>
Line Grouping = 16
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text=""/>
Clear selection
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="0"/>
Show Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="65536"/>
Show Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="131072"/>
Show Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)
</$button>

<$button>
<$action-setfield $tiddler="$:/state/mcr CharRef CharacterListBase" text="196608"/>
Show Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)
</$button>

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

@@font-family: "Lucida Console", Courier, monospace;
<$list filter="[{$:/state/mcr CharRef LineGrouping}!match[]else[10]] " variable=line_grouping>
<$list filter="[[$:/state/mcr CharRef CharacterListBase]get[text]!match[]]">
<$list filter="[range[512]subtract[1]multiply[128]add{$:/state/mcr CharRef CharacterListBase}]" variable=cur_block>
<h2><<cur_block>></h2>
<$list filter="[range[128]subtract[1]] +[add<cur_block>] " variable=cur_code>
<$macrocall $name=CharRef ur_code=<<cur_code>> ur_line_grouping=<<line_grouping>> />
</$list>
</$list>
</$list>
</$list>


TiddlyWiki\Unicode Codepoints Used

TWCard Unicode Extract
```
\define dec_to_u_hex4()
<$list variable=cur_d4 filter="[[$(dec_num)$]divide[16]floor[]divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d4 filter="[[0]subtract<cur_d4>multiply[16]multiply[16]multiply[16]add[$(dec_num)$]]"
><$list variable=cur_d3 filter="[<rem_d4>divide[16]floor[]divide[16]floor[]]"
><$list variable=rem_d3 filter="[[0]subtract<cur_d3>multiply[16]multiply[16]add<rem_d4>]"
><$list variable=cur_d2 filter="[<rem_d3>divide[16]floor[]]"
><$list variable=rem_d2 filter="[[0]subtract<cur_d2>multiply[16]add<rem_d3>]"
><$list variable=hex filter="[[;]addsuffix<cur_d4>addsuffix[;]addsuffix<cur_d3>addsuffix[;]addsuffix<cur_d2>addsuffix[;]addsuffix<rem_d2>split[;10]join[A]split[;11]join[B]split[;12]join[C]split[;13]join[D]split[;14]join[E]split[;15]join[F]split[;]join[]]"
>\u<<hex>></$list><!--hex
--></$list><!--rem_d2
--></$list><!--cur_d2
--></$list><!--rem_d3
--></$list><!--cur_d3
--></$list><!--rem_d3
--></$list><!--cur_d4
-->
\end
\define entry_hexcode(ur_char, ur_code_page)
<$list variable=cur_codepage filter="""[[$ur_code_page$]!match[]else[0]multiply[256]]""">
<$list variable=dec_num filter="""[range[256]add<cur_codepage>]""">
<$wikify name=hex_unicode text=<<dec_to_u_hex4>> >
<$list filter="""[[$ur_char$]regexp<hex_unicode>]""" variable=match_text>
-$ur_char$-<<hex_unicode>>-&amp;#<<dec_num>>;
</$list><!--match_text-->
</$wikify><!--hex_unicode-->
</$list><!--cur_unicode-->
</$list><!--cur_unicode-->
\end
\define unicode_points(ur_pk)
<$list variable=code_page filter="[[$:/state/unicode_points_codepage]get[text]else[0]]">

Code page = <<code_page>> <$button

style="margin-left:30px">
<$list variable="next_page" filter="[<code_page>add[1]]"><$action-setfield $tiddler="$:/state/unicode_points_codepage" text=<<next_page>>/></$list>
Next page
</$button><$button

style="margin-left:30px">
<$action-setfield $tiddler="$:/state/unicode_points_codepage" text="0"/>
Reset
</$button><br>


<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]count[]!match[1]!match[0]]">-&#x005D;-\u005D-&amp;#93;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u0060]count[]!match[1]!match[0]]">-&#x0060;-\u0060-&amp;#96;
<br>
<br>
</$list><!--cur_char-->
<$list variable=cur_char filter="[[$ur_pk$]get[text]splitregexp[\u005D]join[]splitregexp[\u0060]join[]split[]each:value[]sort[]]">-<<cur_char>>-
<$macrocall $name=entry_hexcode ur_code_page=<<code_page>> ur_char=<<cur_char>> />
<br>
<br>
</$list><!--cur_char-->
</$list><!--code_page-->
\end

<<unicode_points "UrPK">>

TiddlyWiki\Upload File

TWCard FileSystem Extract
!! Drag and drop
* Drag a file icon from the Windows Desktop or Windows Explorer over the Wiki until you see a top-margin green bar show
* Release the mouse to drop the file -> Opens card

!! Import Card
* Review the file list and uncheck and undesired import objects
* Click button Import -> Creates Cards

!! BrowseWidget

* Create a $browse tag -> Makes button
* Click button Choose File -> Opens dialog
* Choose a file -> Closes dialog, opens Card

!! Import Card
* Review the file list and uncheck and undesired import objects
* Click button Import -> Creates Cards

```
<$browse />
```

TiddlyWiki\Video and Audio

TWCard Video Audio
* Title = mcr glbl_ext_av
* Tag = `$:/tags/Macro`
* Note: The paths are relative to the current website. You cannot load Video or Audio content from other websites due to browser restrictions.

* Note: You can add attribute `poster="placeholder.png" ` to the Video tag if you have a specific image you want instead of the video's first frame

```
\define glbl_ext_video(UrFolder,UrVideo,UrTime)
<video width="320" height="180"
controls preload="metadata">
<source src="$UrFolder$/$UrVideo$.mp4#t=$UrTime$" type=
"video/mp4">
Your browser does not support the HTML 5 video tag.
</video>
\end
\define glbl_ext_audio(UrFolder,UrAudio,UrTime)
<audio controls preload="none">
<source src="$UrFolder$/$UrAudio$.mp3#t=$UrTime$" type=
"audio/mp3">
Your browser does not support the HTML 5 audio tag.
</audio>
\end

<!--|v
* Hard-coded to only use MP4 files

<<glbl_ext_video "MyVideosSubFolder" "MyVideoFile" "00:01:00">>

<<glbl_ext_video "file:///C:/UrFolder/UrSubFolder" "UrFilenameNoExtension" "00:01:00">>
^|-->
<!--|v
<<glbl_ext_audio "MyAudioSubFolder" "MyAudioFile" "00:01:00">>
^|-->

TiddlyWiki\View All Cards

TWCard CodeLibrary Extract
```
<$list filter="[all[tiddlers]!tag[EXTLINK]!tag[IMG]!tag[INDEX]!tag[MCR]!tag[META]!has[draft.of]!is[image]!is[tag]!is[system]has[tags]!prefix[undefined]sort[title]]">
<hr>
<h2><$link to=<<currentTiddler>> /></h2>
{{||$:/core/ui/ViewTemplate/tags}}
<$transclude mode="block"/>
</$list>

TiddlyWiki\Wikify Text

TWCard Extract Text
```
<$wikify name=str_text_out text="&#65;">
A = <<str_text_out>>
</$wikify>

<$wikify name=str_text_out text="''bold font''" output=html>
B = <<str_text_out>>
</$wikify>

TiddlyWiki\WikiText Formatting

TWCard Formatting Text CodeLibrary
You can type most standard text without problems. Leading, repeated, or paired special characters may need escaped.

!Vertical Spacing

```
Pressing enter at the end of a line does not start a new paragraph.
Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph.
Press enter twice.
```

For example, see how the above two paragraphs are shown below:

Pressing enter at the end of a line does not start a new paragraph.
Both of these lines are one paragraph.

You must leave a blank line between text lines to get a paragraph.
Press enter twice.


!Leading Special Characters

!!Bulleted List Entry

```
*Bulleted List Entry
```

*Bulleted List Entry

Leading with an asterisk creates a bulleted list entry. To escape, prefix with four single-quotes.

If you want a single blank line between two bullet points, use a !''''! Heading Line without any title text.

```
''''*Bulleted List Entry
```

''''*Bulleted List Entry

!!Heading Line

```
!Heading Line
```

Starting a new paragraph line with an exclamation mark (!) results in a heading line.

```
!Heading Line
```

The above heading markup starts with an exclamation mark. To escape, prefix with four single-quotes.

```
''''!Heading Line
```

''''!Heading Line

!!Mono-spaced Text Block

```
 ```
 Mono-spaced Text Block
 ```
```

```
Mono-spaced Text Block
```

Leading with a triple back-tick creates a mono-space text block. To escape, surround the triple back-tick with doubled square-brackets.

```
[[''']] Regular typeface
```

[[```]] Regular typeface

!!Numbered List Entry

```
#Numbered List Entry
```

#Numbered List Entry

Leading with a pound-sign creates a numbered list entry. To escape, prefix with four single-quotes.

```
''''#Numbered List Entry
```

''''#Numbered List Entry

!!Quoted text block
```
<<<
Quoted text block
<<<
```

<<<
Quoted text block
<<<

Leading with a triple less-than creates a quoted text block. To escape, surround the 

```
''''<<< Unquoted text
```

''''<<< Unquoted text

!!URL Links

```
https://tiddlywiki.com/
```

https://tiddlywiki.com/

Start text with an "http'''':/''''/" "http'''':/''''/" will create a URL link. To escape, place four single-quotes before the colon and between the double forward-slashes.

```
https'''':/''''/tiddlywiki.com/
```

https'''':/''''/tiddlywiki.com/


!Repeated Special Characters

```
''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`
```

''Bold Text'' //Italic Text// ~~Strike-through Text~~ __Underlined Text__ ^^Raised-Small Text^^ ,,Lowered-Small Text,, `Mono-spaced Text`

A number of repeated special characters are used as Wiki Markup to format text. To escape, place four single-quotes between the doubled characters or surround the doubled characters with doubled square-braces.

```
[['']]Bold Text[['']] /''''/Italic Text/''''/ ~''''~Strike-through Text~''''~ _''''_Underlined Text_''''_ ^''''^Raised-Small Text^''''^ ,'''',Lowered-Small Text,'''', [[`]]Mono-spaced Text[[`]]
```

[['']]Bold Text[['']] /''''/Italic Text/''''/ ~''''~Strike-through Text~''''~ _''''_Underlined Text_''''_ ^''''^Raised-Small Text^''''^ ,'''',Lowered-Small Text,'''', [[`]]Mono-spaced Text[[`]]

!Paired Special Characters

!!Literal Text

```
[[Literal Text]]
```

[[Literal Text]]

Surrounding text with doubled square-brackets shows the literal surrounded text without applying formatting. To escape, place four single-quotes between the first doubled square-brackets.

```
[''''[Literal Text]]
```

[''''[Literal Text]]

!!Transcluded Text

```
{{Other Tiddler Title}}

Note: The other tidder's content is "Other Tiddler Transcluded Text".
```

{{Other Tiddler Title}}

Surrounding text with doubled curly-braces shows the full content of another tiddler. To escape, place four single-quotes between the first doubled curly-braces.

```
{''''{Other Tiddler Title}}
```

{''''{Other Tiddler Title}}

!!HTML Markup

```
<b>HTML Markup</b>
```

<b>HTML Markup</b>

Surrounding text with angled-brackets uses HTML formatting. To escape, rename the first angle-bracket to &lt'''';

```
&lt;b>HTML Markup</b>
```

&lt;b>HTML Markup</b>

!!HTML Literals

```
&lt;

Note: &lt; represents a left angle-bracket, or the less-than symbol (<).
```

&lt;

Surrounding text with an ampersand (&) and a semi-colon translate to an HTML literal. To escape, place four single-quotes after the ampersand.

```
&lt;
```

&''''lt;


!!CSS Styles

You can apply CSS styles in-line with the text. Make sure you put the semi-colon at the end of the style list.

```
You can apply @@background-color:yellow; CSS styles @@ in-line with the text.
```

You can apply @@background-color:yellow; CSS styles @@ in-line with the text.


!!Tables

```
|!Cell1 |!Cell2 |
|Cell3 |Cell3 |

|^top left |^ top center |^ top right|
|middle left | middle center | middle right|
|,bottom left |, bottom center |, bottom right|


To merge a table cell with the one above, use the special cell text ~. To merge a cell with the one to its left use the text <. To merge one to its right use >. For example:

|Cell1 |Cell2 |Cell3 |Cell4 |
|Cell5 |Cell6 |Cell7 |<|
|Cell5 |~|Cell7 |Cell8 |
|>|Cell9 |Cell10 |Cell11 |

assigns the CSS classes "myclass" and "anotherClass" to the table
gives the table the caption "This is a caption"
adds a header row of cells with the text "Header"
adds a footer row of cells with the text "Footer"
|myclass anotherClass|k
|This is a caption |c
|Cell1 |Cell2 |
|Cell3 |Cell3 |
|Header|Header|h
|Footer|Footer|f
```

TiddlyWiki\Word Wrap

TWCard Text WordWrap
!! Hard-line breaks using CSS styles

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
.tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

* Note: When using this alternate CSS, wiki text markup will be ignored unless preceded by a double-spaced line
* Note: The card's Preview window was not using the same CSS stylesheet changes as the committed card

Sample Code:

```
*bullet 1
*bullet 2
*bullet 3
Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a ",,,,",,,," wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

*bullet 4 requires a preceding double-spaced line to be interpreted as wikitext
```

<<<
Results:

```
* bullet 1
* bullet 2
* bullet 3

Pressing enter creates a new line, and does not continue the previous wikitext bullet line.
Every hard line break is shown like you would see in a text file or a """ wikitext block.
*These lines start with a wikitext code just like the ones above.
*Leading wikitext codes are ignored until preceded by a double-spaced line

* bullet 4 requires a preceding double-spaced line to be interpreted as wikitext
```
<<<

!! Apply stylesheet to cards with specific tag `linewrap`

* New card name = UrStylesheetCardName
* Tag = $:/tags/Stylesheet

```
[data-tags*="linewrap"] .tc-tiddler-body {
  word-break: normal;
  word-wrap: break-word;
  white-space: pre-wrap;
}
```

!! Apply Styles to In-line Text

* Start a text block with @,,,,@ and the CSS styles with no spaces

Sample Code:

```
@@word-break:normal;word-wrap:break-word;white-space:pre-wrap;
These are
separate lines
here
@@

This is
one big
line
```

<<<
Result:

```
These are
separate lines
here

This is one big line
```
<<<

* or start in the middle of a text block

Sample Code:

```
This is
one big
line@@word-break:normal;word-wrap:break-word;white-space:pre-wrap; here.
Followed by a second line,
and a third here@@. And this
extends the
third line.
```

<<<
Result:

```
This is one big line here.
Followed by a second line,
and a third here. And this extends the third line.
```
<<<

TotalCommander

DOC
<<glbl_article_list>>

TotalCommander\Create new Text File

Text FileSystem AndroidOS
"""
[Total Commander directory]
- [Top of the directory]
- Hold down on the '..' button to see the menu -> Opens menu
- - or Hold down on any subdirectory name to see the menu -> Opens menu

- [context menu]
- Click option New Text file -> Opens dialog

- [Create new text file dialog]
- Enter a new text file name
- Click button OK -> Closes dialog

- [Directory list]
- Note: The new file was added to the current folder

TotalCommander\Local file desktop shortcut

AssignVariable FileSystem AndroidOS
"""
Note: You can also create a Website shortcut on the Desktop from Google Chrome
Note: You can also create a Browser shortcut to a local folder

[Total Commander directory]
- Hold down on file entry named like *.html -> Opens menu

- [context menu]
- Click option Create link on desktop -> Opens dialog

- [Create link dialog, main page, command line section]
- Click button '>>' -> Opens dialog

- [Choose app dialog, main page]
- Click option Choose app * -> Navigates page

- [Choose app dialog, Choose app * page]
- Click option Chrome -> Navigates page

- [Create link dialog, main page]
- Click button OK / Apply -> Closes dialog

[Android Desktop icons]
- Note: The icon was added to the desktop automatically

TW Project

DOC
<<glbl_article_list>>

TW Project\Check app

TWCard CodeLibrary
<<ext "Project Check app">>

Goal: Find food by aisle

TW Project\Code Snapshot

TWCard CodeLibrary
<<ext "TW Snapshot Review">>

Goal: Browse the code inside the WIki file

<<ext "TW Snapshot v5d01d23 main-site">>

<<ext "TW Snapshot v5d01d23 empty">>

<<ext "TW Snapshot v5d01d23 pre-release">>

<<ext "TW Snapshot v5d01d23 update">>

TW Project\Features list

TWCard CodeLibrary
<<ext "TW Features">>

Goal: Demonstrate every Wiki command and option

TW Project\Javascript Plugin instructions

TWCard JavaScriptCode
<<ext "TW Create Javascript Plugin">>

TW Project\Shuffle List addon

TWCard CodeLibrary Filter
<<ext "Shuffle List Entries">>

TW Project\Text Replace addon

TWCard Text AssignVariable
<<ext "TW Addon Text Replace">>

Goal: Add text replacement functionality to the standard TWCard editor

TW Project\TiddlyWiki Manual

TWCard CodeLibrary
<<ext "TW Manual">>

Goal: Explain the Single-Page Quine Wiki architecture

TW Project\TW JS Pretty

TWCard JavaScriptCode Formatting
<<ext "TW JS Pretty">>

Goal: Upload a text file and comment on each line, table or function

TW Project\Wiki Empty Setup

TWCard HTMLCode Extract
<<ext "Empty Wiki Setup">>

Goal: Use the empty TW document and generate a static HTML page

Unicode

DOC
<<glbl_article_list>>

Unicode\Code Blocks

Unicode Text CodeLibrary
<<ext "Unicode Block 00-Basic Latin">>

<<ext "Unicode Block 01-Latin Supplement">>

<<ext "Unicode Code Block List">>

<<ext "Unicode Block Planes">>

Base Multilingual Plane (BMP = 0-65535, 0x0-0xFFFF)

Supplementary Multilingual Plane (SMP = 65536-131071, 0x10000-0x1FFFF)

Supplementary Ideographic Plane (SIP = 131072-196607, 0x2000-0x2FFFF)

Tertiary Ideographic Plane (TIP = 196608-262143, 0x3000-0x3FFFF)

Note: Planes 4 to 13 (planes 4 to D in hexadecimal): No characters have yet been assigned to Planes 4 through 13

Note: Plane 14 (E in hexadecimal), the Supplementary Special-purpose Plane (SSP)

Note: Plane 15 (plane F in hexadecimal) = Supplementary Private Use Area-A (PUA-A), is only available for use by parties outside the ISO and the Unicode Consortium.

Note: Plane 16 (plane 10 in hexadecimal) = Supplementary Private Use Area-B (PUA-B), is only available for use by parties outside the ISO and the Unicode Consortium.

Unicode\Latest Version

Unicode Text CodeLibrary
<<ext "Unicode Character Database">>

All files for the most up-to-date version of the Unicode Character Database can be found at: http://www.unicode.org/Public/UCD/latest/.

The latest text file databases are at https://www.unicode.org/Public/UCD/latest/ucd/. The latest set of text file databases is in a ZIP file at https://www.unicode.org/Public/UCD/latest/ucd/UCD.zip.

The list of Unicode Code Blocks are in the text database https://www.unicode.org/Public/UCD/latest/ucd/Blocks.txt.

There is a list of names for the Unicode Code Points at https://www.unicode.org/Public/UCD/latest/ucd/Index.txt. There same list is sorted in Code Point order at https://www.unicode.org/Public/UCD/latest/ucd/NameAliases.txt. Each hex code can have multiple names.

The unique list of Unicode Code Points is at https://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt. There is a character name and possibly an alternative name on each row.


VBNetCode

DOC
<<glbl_article_list>>

VBNetCode\Application Startup require DLLs

CodeLibrary VBCode
```
Option Strict On
Namespace My
    Partial Friend Class MyApplication
        Sub Main(sender As Object, e As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs) Handles Me.Startup
            Mx.Want.TestReferencedAssemblies_errhnd(e)
            'Next goes to frmInput_1_Load, then Want.Compile_And_Run_Script
        End Sub
    End Class
End Namespace

Namespace Mx
    Partial Public Class Want
        Public Shared Sub TestReferencedAssemblies_errhnd(ur_startup_event_args As Microsoft.VisualBasic.ApplicationServices.StartupEventArgs)
            Dim objERR_LIST = New ErrListBase : Try
                Call Assistant.TestReferencedAssemblies()

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                MsgBox(objERR_LIST.ToString, , My.Application.Info.Title)
                ur_startup_event_args.Cancel = True
            End If
        End Sub 'TestReferencedAssemblies_errhnd
    End Class 'Want
    
    Partial Public Class Assistant
        Public Shared Sub TestReferencedAssemblies()
            'Will error if DLL does is not available
            Dim objV1 = System.Data.SqlClient.SortOrder.Ascending
        End Sub 'TestReferencedAssemblies
    End Class 'Assistant
End Namespace 'Mx

VBNetCode\Checksum calculate

Numbers Extract VBCode
I want a .Net program to calculate the SHA512 hash of a file

```
Dim strHASH_KEY = ""
Using objSHA = New System.Security.Cryptography.SHA512Managed
    Using stmFILE = System.IO.File.OpenRead(flnDATA)
        strHASH_KEY = "[" & System.BitConverter.ToString(objSHA.ComputeHash(stmFILE)).Replace("-", "").ToLower & "]"
        'Convert.ToBase64String(
    End Using
End Using

VBNetCode\Copy File Lines

FileSystem Extract VBCode
```
Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT("TXT"), bolAPPEND_FILE, gUTF8_FileEncoding)
	Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
		While stmDATA.EndOfStream = False
			'Character copy
			Dim intENTRY = stmDATA.Read()
			Dim strENTRY = ChrW(intENTRY)
			stmOUT_FILE.Write(strENTRY)
			
			'Line copy
			Dim strLINE = stmDATA.ReadLine()
			stmOUT_FILE.WriteLine(strLINE)
		End While 'stmDATA
	End Using 'stmDATA
End Using 'stmOUT_FILE
```

Split File into chunks of 100,000 lines each

```
Dim intFILE_COUNT = 0
Dim intLINE_COUNT = 0
Using stmDATA = New System.IO.StreamReader(flnDATA, gUTF8_FileEncoding)
	While stmDATA.EndOfStream = False
		intFILE_COUNT += 1
		intLINE_COUNT = 0
		Dim strFILE_COUNT = intFILE_COUNT.ToString()
		If Len(strFILE_COUNT) = 2 Then
			strFILE_COUNT = "c" & strFILE_COUNT
		ElseIf Len(strFILE_COUNT) = 3 Then
			strFILE_COUNT = "d" & strFILE_COUNT
			
			End If 'strFILE_COUNT
		
		strFILE_COUNT = "e" & strFILE_COUNT
		Using stmOUT_FILE = New System.IO.StreamWriter(flnDATA.gCopy.dAppendEXT(strFILE_COUNT & ".TXT"), False, gUTF8_FileEncoding)
			While stmDATA.EndOfStream = False
				Dim strLINE = stmDATA.ReadLine()
				stmOUT_FILE.WriteLine(strLINE)
				intLINE_COUNT += 1
				
				If intLINE_COUNT >= 100000 Then
					Exit While
					
					End If
				
				End While 'stmDATA
			
			End Using 'stmOUT_FILE

		End While 'stmDATA
	
	End Using 'stmDATA

VBNetCode\DotNet Core Compile EXE

Extract VBCode WindowsOS
[https://github.com/dotnet/core/issues/5409]

<<<
In .NET 5 the single-file publish may produce more than one file and it's by design. See the expected behavior described here: 

https://github.com/dotnet/designs/blob/main/accepted/2020/single-file/design.md#user-experience

In 3.1 single-file is basically just a self-extracting executable - it writes everything into temp and runs from there. As such for the running app nothing really changes (everything is a file, with a path and so on).

In 5 we don't write to disk by default, all managed assemblies are loaded directly from the executable. The problem is native libraries - it's technically VERY difficult to include a random .dll in an executable and run it from the executable directly.

If you only take the .exe and run it, it won't work - it needs those additional files.

If you need .NET 5 but want the self-extracting behavior you can set IncludeAllContentForSelfExtract=true and it will behave basically the same as in 3.1.

There's also a "hybrid" mode IncludeNativeLibrariesForSelfExtract=true which will produce just one executable and that will write the native libraries to temp and then run.
<<<

User-replaced value = UrProjectDir

[UrProjectDir folder]
- Start with [[VBNetCode\DotNet Core New Project]]

"""
[Windows CLI]
- [Compile into an EXE]
- `dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep`
- Text output ->
"""

```
Microsoft (R) Build Engine version 16.8.0+126527ff1 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

  Determining projects to restore...
  All projects are up-to-date for restore.
  t3 -> UrProjectDir\bin\Release\net5.0\win10-x64\UrProjectDir.dll
  t3 -> UrProjectDir\Dep\
```

"""
[UrProjectDir folder]
- [Look for the new folders]
- New sub-folders: bin, Dep
- Note: The compiled program is in the Dep subfolder named UrProjectDir.exe
- - The UrProjectDir.pdb file is used for debugging purposes and would not normally be deployed with your EXE file

[Windows CLI]
- [Remove the temporary folders in the UrProjectDir]
- `rd bin /s /q`
- `rd obj /s /q`
- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output shows as if you ran the command `dotnet run`

- Note: You can output the `System.AppContext.BaseDirectory` to find the Temp that holds the uncompressed program
"""

"""
[Program.vb file]
- [Replaces lines in Main sub]
- `Console.WriteLine(System.AppContext.BaseDirectory)`

[Windows CLI]
- [Compile into an EXE]
- `dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true -p:PublishTrimmed=true --output Dep`
- Note: If running DotNet Core 3.1,
- - `dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true -p:PublishSingleFile=true`
- -  The "--self-contained" option is incompatible with the "-p:PublishReadyToRun=true" and "-p:PublishSingleFile=true" options

- Note: When you choose the Portable publish option, you'll get a package that is capable of running on either x86 (32-bit) machines and x64 (64-bit) machines
- - The next run would have to JIT compile the application again as it is used
- - The advantage here is that you'd only need to distribute one package, and it'll run on both x86/x64 machines
- - `dotnet publish -c Release -r portable --self-contained`

- [Remove the temporary folders in the UrProjectDir]
- `rd bin /s /q`
- `rd obj /s /q`
- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output =
"""

```
C:\Users\UrUsername\AppData\Local\Temp\.net\UrProjectDir\SomeRandom-8-letters.SomeRandom-3-letters\
```

"""
- Note: This folder gets created on the first run the of UrProjectDir.exe
- - The second run starts faster because the files have already been extracted to this temporary folder
- - You can delete the temporary folder, and running the UrProjectDir.exe will create it again.

- Note: You can specify a different temporary folder by setting the Environment Variable `DOTNET_BUNDLE_EXTRACT_BASE_DIR`

- `SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%USERPROFILE%\Downloads\UrProjectDir\tmp`
- Note: You can set the Environment Variable in a batch file and it will not be saved for new Windows CLI windows.
- - To set it permanently, use `Control Panel` \ `System and Security` \ `System` \ `Advanced systems settings` \ `Advanced` tab \ `Environment Variables` button \ top or bottom section \ `New` button, Variable Name = `DOTNET_BUNDLE_EXTRACT_BASE_DIR`, Variable Value = `UrFullPathToTempDirectory`, `OK button`
- - Trying to use a relative directory path ends up not running the executable

- [Run the project]
- `Dep\UrProjectDir.exe`
- Text output = 
"""

```
C:\Users\UrUsername\Downloads\UrProjectFolder\tmp\UrProjectFolder\SomeRandom-8-letters.SomeRandom-3-letters\
```

"""
- [Review the size of the TMP folder]
- `dir tmp /s`
- Text output = 23 Files, 8 Dirs

- [Remove the temporary directory]
- `rd tmp /s /q`

[UrProjectDir\Dep folder]
- [Create a script to run the project and clean up the temporary files]
- New file = UrProjectDir.cmd

[UrProjectDir.cmd file]
"""

```
@@ECHO OFF
SET CUR_DIR=%~dp0
SET DOTNET_BUNDLE_EXTRACT_BASE_DIR=%CUR_DIR%tmp
"%CUR_DIR%UrProjectDir.exe"
rd "%CUR_DIR%bin" /s /q 2> nul
rd "%CUR_DIR%obj" /s /q 2> nul
rd "%CUR_DIR%tmp" /s /q 2> nul
```

"""
[Windows CLI]
- [Run the clean-execution script]
- `Dep\UrProjectDir.cmd`
- Note: There is no tmp subfolder

VBNetCode\DotNet Core Installation using Binaries

VBCode WindowsOS
"""
[https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net50]
"""

<<<
As an alternative to the Windows installers for .NET, you can download and manually install the SDK or runtime. Manual install is usually performed as part of continuous integration testing. For a developer or user, it's generally better to use an installer.

Both .NET SDK and .NET Runtime can be manually installed after they've been downloaded. If you install .NET SDK, you don't need to install the corresponding runtime. First, download a binary release for either the SDK or the runtime from one of the following sites:

https://dotnet.microsoft.com/download/dotnet/5.0

https://dotnet.microsoft.com/download/dotnet-core

Create a directory to extract .NET to, for example %USERPROFILE%\dotnet. Then, extract the downloaded zip file into that directory.

By default, .NET CLI commands and apps won't use .NET installed in this way and you must explicitly choose to use it. To do so, change the environment variables with which an application is started:

```
set DOTNET_ROOT=%USERPROFILE%\dotnet
set PATH=%USERPROFILE%\dotnet;%PATH%
set DOTNET_MULTILEVEL_LOOKUP=0
```

This approach lets you install multiple versions into separate locations, then explicitly choose which install location an application should use by running the application with environment variables pointing at that location.

When DOTNET_MULTILEVEL_LOOKUP is set to 0, .NET ignores any globally installed .NET version. Remove that environment setting to let .NET consider the default global install location when selecting the best framework for running the application. The default is typically C:\Program Files\dotnet, which is where the installers install .NET.
<<<

"""
[https://docs.microsoft.com/en-us/dotnet/core/install/how-to-detect-installed-versions?pivots=os-windows]
"""

<<<
When you install .NET from an installer or script, it's installed to a standard folder. Much of the time the installer or script you're using to install .NET gives you an option to install to a different folder. If you choose to install to a different folder, adjust the start of the folder path.

dotnet executable in C:\program files\dotnet\dotnet.exe

.NET SDK in C:\program files\dotnet\sdk\{version}\

.NET Runtime in C:\program files\dotnet\shared\{runtime-type}\{version}\
<<<

VBNetCode\DotNet Core Installed Path

FileSystem Extract VBCode
"""
[Windows CLI]
- [Run the system information report]
- `dotnet --info`
"""

```
.NET Core SDK (reflecting any global.json):
 Version:   3.1.401
 Commit:    5b6f5e5005

Runtime Environment:
 OS Name:     Windows
 OS Version:  10.0.18363
 OS Platform: Windows
 RID:         win10-x64
 Base Path:   C:\Program Files\dotnet\sdk\3.1.401\

Host (useful for support):
  Version: 3.1.7
  Commit:  fcfdef8d6b

.NET Core SDKs installed:
  3.1.301 [C:\Program Files\dotnet\sdk]
  3.1.401 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
  Microsoft.AspNetCore.All 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
  Microsoft.AspNetCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.AspNetCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
  Microsoft.NETCore.App 2.1.21 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.NETCore.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
  Microsoft.WindowsDesktop.App 3.1.5 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]
  Microsoft.WindowsDesktop.App 3.1.7 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
  https://aka.ms/dotnet-download
```

VBNetCode\DotNet Core New Project

Extract VBCode
[https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-new]

<<<
You can run dotnet new --list or dotnet new -l to see a list of all installed templates. If the TEMPLATE value isn't an exact match on text in the Templates or Short Name column from the returned table, a substring match is performed on those two columns.

Starting with .NET Core 3.0 SDK, the CLI searches for templates in NuGet.org when you invoke the dotnet new command in the following conditions:

* If the CLI can't find a template match when invoking dotnet new, not even partial.
* If there's a newer version of the template available. In this case, the project or artifact is created but the CLI warns you about an updated version of the template.
<<<

[https://docs.microsoft.com/en-us/dotnet/core/deploying/deploy-with-cli]

"""
User-replaced value = UrProjectDir

[Windows CLI]
- [Navigate to the User Downloads folder]
- `cd %USERPROFILE%\Downloads`
- [Create a new DotNet Core project named UrProjectDir]
- `dotnet new console -lang VB -o UrProjectDir`
- Text output =
"""

```
Getting ready...
The template "Console Application" was created successfully.

Processing post-creation actions...
Running 'dotnet restore' on C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj...
  Determining projects to restore...
  Restored C:\Users\UrUsername\Downloads\UrProjectDir\UrProjectDir.vbproj (in 65 ms).
Restore succeeded.
```

"""
- [Navigate to the new UrProjectDir]
- `cd UrProjectDir`

[UrProjectDir folder]
- [Look for the new files and folders]
- New files: UrProjectDir.vbproj and Program.vb
- New sub-folder: obj

[Windows CLI]
- [Download a dependency]
- `dotnet add package Figgle`
- Text output =
"""

```
  Determining projects to restore...
  Writing C:\Users\Dad\AppData\Local\Temp\tmpE018.tmp
info : Adding PackageReference for package 'Figgle' into project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info :   GET https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json
info :   OK https://api.nuget.org/v3/registration5-gz-semver2/figgle/index.json 104ms
info : Restoring packages for C:\Users\Dad\Downloads\t3\t3.vbproj...

info : Installing runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple 4.3.0.
info : Installing runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl 4.3.0.

info : Package 'Figgle' is compatible with all the specified frameworks in project 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : PackageReference for package 'Figgle' version '0.4.0' added to file 'C:\Users\Dad\Downloads\t3\t3.vbproj'.
info : Committing restore...
info : Writing assets file to disk. Path: C:\Users\Dad\Downloads\t3\obj\project.assets.json
log  : Restored C:\Users\Dad\Downloads\t3\t3.vbproj (in 8.04 sec).
```

"""
[Program.vb file]
- [Replace lines in Main sub]
- `Console.WriteLine(Figgle.FiggleFonts.Standard.Render("Hello, World!"))`

[Windows CLI]
- [Compile into an EXE and run it]
- `dotnet run`
- If you did not enter the program line incorrectly, Text output =
"""

```
Program.vb(5,79): error BC30037: Character is not valid.

The build failed. Fix the build errors and run again.
```

"""
- If you entered the program line correctly, Text output shows Hello World in a large font
"""

VBNetCode\DotNetCore Installation using Installer

VBCode WindowsOS
"""
[https://dotnet.microsoft.com/platform/support/policy/dotnet-core]
- 2020m11d24: .NET 5 is the current version of DotNet Core. It was released on November 10, 2020.

[https://dotnet.microsoft.com/download/dotnet-core]
- [Supported versions, record Version = .NET 5.0]
- Click link .NET 5.0 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/5.0]
- [record Release Information = v5.0.0, Build Apps column]
- [SDK grid, record OS = Windows]
- Click link x86 -> Navigates page

[https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-windows-x64-installer]
- Auto-download started -> Saves file

[Local Computer Downloads folder]
- [filename = dotnet-sdk-5.0.100-win-x64.exe]
- Run program -> Opens form

[Microsoft .NET SDK 5.0.100 (x64) Installer window]
- Click button Install -> Windows dialog
- Question: Do you want to allow the program to make changes to your computer?
- Click button Yes -> Closes dialog
- Wait for progress bar to complete -> Navigates page
- Note: Installation was successful
- Click button Close -> Closes window

[[VBNetCode\DotNet Core Installed Path]]

VBNetCode\File Exists

FileSystem Extract VBCode
```
Dim bolFILE_EXISTS = System.IO.File.Exists(flnDATA)

VBNetCode\File Size

FileSystem Extract VBCode
```
Dim sioFILE = New System.IO.FileInfo(flnDATA)
Dim intFILE_SIZE = sioFILE.Length

VBNetCode\Global functions passed as Classes

CodeLibrary AssignVariable VBCode
```
    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

VBNetCode\In-Memory Compile

CodeLibrary Extract VBCode
```
Namespace Mx
    Public Class ScriptRun
        ' Build a Hello World program graph using 
        ' System.CodeDom types.
        Public Class enmC_V_J
            Inherits bitBASE
            Public Shared CSharp As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared VisualBasic As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
            Public Shared JScript As enmC_V_J = TRow(Of enmC_V_J).glbl.NewBitBase()
        End Class 'enmC_V_J

        Public Shared Function RunCode(ur_provider As Mx.ScriptRun.enmC_V_J, ur_input_script As String, ur_assembly_folder As String) As String
            Dim strSOURCE_CODE = ur_input_script
            Dim stpERR_MSG = Strapd()
            Dim stpCODE_FILE = Strapd()
            ' Configure a CompilerParameters that links System.dll and produces the specified executable file.
            Dim objAPP_DOMAIN As AppDomain = Nothing
            Dim objCOMPILE_RUNNER As CompilerRunner = Nothing
            Dim objCOMPILER_PARM = New System.CodeDom.Compiler.CompilerParameters
            Dim objCOPMILER_RESULT As System.CodeDom.Compiler.CompilerResults = Nothing
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing

            If stpERR_MSG.Length = 0 Then
                'objAPP_DOMAIN = System.AppDomain.CreateDomain("MyDomain", AppDomain.CurrentDomain.Evidence, CreateSetup())
                'objCOMPILE_RUNNER = objAPP_DOMAIN.CreateInstanceFromAndUnwrap(GetType(CompilerRunner).Assembly.Location, GetType(CompilerRunner).FullName)
                objCOMPILE_RUNNER = New Mx.CompilerRunner
                stpERR_MSG.d(objCOMPILE_RUNNER.Compile(stpCODE_FILE.ToString, ur_provider.name, objCOMPILER_PARM))
            End If

            If stpERR_MSG.Length = 0 Then
                stpERR_MSG.d(objCOMPILE_RUNNER.Run("Mx.Class1", "RetVal"))
            End If

            If objAPP_DOMAIN IsNot Nothing Then
                'AppDomain.Unload(objAPP_DOMAIN)
            End If
            ' Return the results of compilation.
            Return stpERR_MSG.ToString
        End Function 'RunCode

        Public Shared Function CreateSetup() As AppDomainSetup
            Dim retSETUP = New AppDomainSetup
            With retSETUP
                .ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
                .ApplicationName = "TestDLL"
                .DisallowBindingRedirects = False
                .ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
                .LoaderOptimization = LoaderOptimization.MultiDomainHost
            End With
            CreateSetup = retSETUP
        End Function 'CreateSetup
    End Class 'ScriptRun

    Public Class CompilerRunner
        Inherits MarshalByRefObject

        Public cur_assembly As System.Reflection.Assembly = Nothing
        'AppDomain.CurrentDomain.FriendlyName = MyDomain

        Public Function Compile(ur_code As String, ur_provider As String, ur_compiler_parm As System.CodeDom.Compiler.CompilerParameters) As String
            Dim stpERR_MSG = Strapd()
            Me.cur_assembly = Nothing
            Dim provider As System.CodeDom.Compiler.CodeDomProvider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider(ur_provider) 'New Microsoft.VisualBasic.VBCodeProvider 
            Dim objCOMPILER_RESULT = provider.CompileAssemblyFromSource(ur_compiler_parm, ur_code) ' Strapd().d("Namespace Mx").dLine("Public Class Class1").dLine("Public Shared Function RetVal() As String").dLine("RetVal=""Hi""").dLine("End Function").dLine("End Class").dLine("End Namespace"))
            If objCOMPILER_RESULT.Errors.Count = 0 Then
                Me.cur_assembly = objCOMPILER_RESULT.CompiledAssembly

            Else
                stpERR_MSG.dLine("Compile Errors")
                stpERR_MSG.dLine()
                For Each errItem As System.CodeDom.Compiler.CompilerError In objCOMPILER_RESULT.Errors
                    stpERR_MSG.dLine(errItem.ErrorText & " [" & errItem.Line + 5 & "]")
                    stpERR_MSG.dLine()
                    stpERR_MSG.dLine()
                Next errItem

                stpERR_MSG.dLine(ur_code)
            End If 'objCOMPILER_RESULT

            Compile = stpERR_MSG.ToString
        End Function 'Comiple

        Public Function Run(ur_type_name As String, ur_method_name As String) As String
            Dim stpERR_MSG = Strapd()
            Dim t As System.Type = Me.cur_assembly.CreateInstance(ur_type_name).GetType()
            'Dim objRESULT = t.InvokeMember(ur_method_name, System.Reflection.BindingFlags.InvokeMethod, Nothing, Me.cur_assembly, {})
            Dim objMETHOD_MAIN As System.Reflection.MethodInfo = Nothing
            For Each m As System.Reflection.MethodInfo In t.GetMethods
                If m.Name = ur_method_name Then
                    objMETHOD_MAIN = m
                    Exit For
                End If
            Next m

            If objMETHOD_MAIN IsNot Nothing Then
                Dim objRESULT = objMETHOD_MAIN.Invoke(Nothing, Nothing)
                If objRESULT IsNot Nothing Then
                    stpERR_MSG.dLine(objRESULT.ToString)
                End If 'objRESULT
            End If 'objMETHOD_MAIN

            Run = stpERR_MSG.ToString
        End Function 'Run
    End Class 'CompileRunner
End Namespace 'Mx

VBNetCode\Send Keys

AssignVariable VBCode
Send one alt-tab

```
System.Windows.Forms.SendKeys.Send("%{TAB}")
```

Hold down Alt, press alt-tab twice, and release Alt

```
System.Windows.Forms.SendKeys.Send("%({TAB}{TAB})")
```

The Windows key is not so easy to emulate.
- Auto-It or Auto-Hotkey can do more complicated patterns
- VB.Net can use PInvoke to have more capabilities

VBNetCode\Text file to JSON Lines

TWCard Extract VBCode
This outputs a file that can be dragged into TiddlyWiki.

```
<$list variable=cur_char filter="[[UrPK]get[text]splitregexp[\n]join[]split[]each:value[]!match[ ]sort[]]">
<<cur_char>>:
<$list variable=disp_name filter="[[Unicode Char Names]getindex<cur_char>else[missing]]">
<<disp_name>>
</$list><!--disp_name-->
<br>
</$list><!--cur_char-->

[[Unicode Char Names]]
```


```
Dim strFILE_PATH = "UnicodeData.txt"
Dim strOUT_PATH = strFILE_PATH & ".json"
Using stmOUT_FILE = New System.IO.StreamWriter(strOUT_PATH)
	Dim qs = """"
	Dim strESC_DQT = "\" & qs
	stmOUT_FILE.Write("[{""created"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & ",""modified"":" & qs & Now().ToString("yyyyMMddHHmmssfff") & qs & "," &
		qs & "title" & qs & ":" & qs & "Unicode Char Names" & qs & ",""type"":""application/json"",""text"":""{")
	Using stmDATA = New System.IO.StreamReader(strFILE_PATH)
		Dim LINCTR = 0
		While stmDATA.EndOfStream = False
			Dim strLINE = stmDATA.ReadLine()
			Dim intFOUND_SPRTR = InStr(strLINE, ";")
			
			Dim strHEX = Mid(strLINE, 1, intFOUND_SPRTR - 1)
			Dim intCHAR = Cint("&H" & strHEX)
			Dim strCHAR = UCase(strHEX)
			Dim strPREFIX = Left(strCHAR, 2)
			If Len(strCHAR) <> 4 Then
				strPREFIX = ""
			End If
			
			If intCHAR < 32 Then
			  strCHAR = ""
			ElseIf intCHAR > 65534 OrElse
			  strPREFIX = "D8" OrElse
			  strPREFIX = "D9" OrElse
			  strPREFIX = "DA" OrElse
			  strPREFIX = "DB" OrElse
			  strPREFIX = "DC" OrElse
			  strPREFIX = "DD" OrElse
			  strPREFIX = "DE" OrElse
			  strPREFIX = "DF" Then
				strCHAR = "\u" & strHEX
			Else
				strCHAR = CHRW(intCHAR)
				If strCHAR = "\" Then
					strCHAR = "\\\\"
				ElseIf strCHAR = """" Then
					strCHAR = "\\\" & """"
				End If
			End If

			If strCHAR <> "" Then
				LINCTR += 1
				If LINCTR > 1 Then
					stmOUT_FILE.Write(",")
				End If
				stmOUT_FILE.Write("\n    " & strESC_DQT & strCHAR & strESC_DQT & ":" & " " & strESC_DQT & strLINE.Replace("\", "\\").Replace(Chr(10), "\n").Replace(qs, strESC_DQT).Replace("<", "&lt;") & strESC_DQT)
			End If
		End While 'stmDATA
	End Using 'stmDATA
	
	stmOUT_FILE.Write("\n}" & qs & "}]")
End Using 'stmOUT_FILE

VBNetCode\To Hex

Numbers Extract VBCode
"""
Change string with numbers (0 to 9) and/or letters (a-f) into decimal number

[q/a page]
- https://stackoverflow.com/questions/642417/how-do-you-convert-hex-to-decimal-using-vb-net

[sample code]
"""

```
Dim strTEXT = "FF"
Dim strHEX_CODE = "&H" & strTEXT
Dim intNUMBER = CInt(strHEX_CODE)
MsgBox(intNUMBER) -> 255

VBNetCode\Unicode Code Point

<<ext "Microsoft DotNet Char ConvertToUTF32">>

* Note: The index can be any character in the string

```
retval = char.ConvertToUtf32(s:="A", index:=0).Tostring
```

<<<
Result:

```
65
```
<<<

VBNetCode\UserBowl example

CodeLibrary Extract VBCode
```
    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As zapp_folder = TRow(Of enmUN).glbl.Trbase(Of zapp_folder).NewBitBase() : Public Class zapp_folder : Inherits enmUN : End Class
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared background_color As zbackground_color = TRow(Of enmUN).glbl.Trbase(Of zbackground_color).NewBitBase() : Public Class zbackground_color : Inherits enmUN : End Class
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_project_code As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared compiler_exe As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared form_title As zform_title = TRow(Of enmUN).glbl.Trbase(Of zform_title).NewBitBase() : Public Class zform_title : Inherits enmUN : End Class
        Public Shared path As zpath = TRow(Of enmUN).glbl.Trbase(Of zpath).NewBitBase() : Public Class zpath : Inherits enmUN : End Class
        Public Shared script_path As zscript_path = TRow(Of enmUN).glbl.Trbase(Of zscript_path).NewBitBase() : Public Class zscript_path : Inherits enmUN : End Class
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared window_status As zwindow_status = TRow(Of enmUN).glbl.Trbase(Of zwindow_status).NewBitBase() : Public Class zwindow_status : Inherits enmUN : End Class
    End Class

    Public Class enmUR_Color
        Inherits bitBASE
        Public Shared Clear As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Green As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
        Public Shared Red As enmUR_Color = TRow(Of enmUR_Color).glbl.NewBitBase()
    End Class

    Public Class enmUR_Status
        Inherits bitBASE
        Public Shared Show As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
        Public Shared Close As enmUR_Status = TRow(Of enmUR_Status).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'db.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit(Have.WindowsMsgBox, Have.WindowsCboard)
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)
            Private enrBackground_Color As System.Drawing.Color
            Private enrUR_Color As enmUR_Color

            Public ReadOnly Property Background_Color_of_Form As System.Drawing.Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color_of_Form = Me.enrBackground_Color
                End Get
            End Property 'Background_Color_of_Form

            Public Property Background_Color As enmUR_Color
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Background_Color = Me.enrUR_Color
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As enmUR_Color)
                    Dim intCOLOR = System.Drawing.Color.Transparent
                    If value Is enmUR_Color.Red Then
                        intCOLOR = System.Drawing.Color.Red

                    ElseIf value Is enmUR_Color.Green Then
                        intCOLOR = System.Drawing.Color.Green
                    End If

                    Me.enrBackground_Color = intCOLOR
                    Me.enrUR_Color = value
                    Me.v(enmUB.contents) = value.name
                End Set
            End Property 'Contents

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_bowlname_is(ur_cmp As enmUN) As Boolean
                v_bowlname_is = AreEqual(Me.v(enmUB.bowl_name), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_cmp As enmUR_Color) As Boolean
                v_is = AreEqual(Me.Contents, ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit(ur_windowsmsgbox_env As Have.glblWindowsMsgBox, ur_windowscboard_env As Have.glblWindowsCboard)
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = ur_windowsmsgbox_env.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        ur_windowscboard_env.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Dim strASSEMBLY_EXE = mt
                Try
                    strASSEMBLY_EXE = My.Application.Info.Title
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_FOLDER = FileNamed()
                Try
                    flnASSEMBLY_FOLDER.wAssemblyDir(My.Application.Info)
                Catch ex As System.Exception : End Try

                Dim flnASSEMBLY_PATH = flnASSEMBLY_FOLDER.gCopy.d(strASSEMBLY_EXE)
                Me.SelKey(enmUN.app_name).Contents = flnASSEMBLY_PATH.FileGroup
                Me.SelKey(enmUN.app_path).Contents = flnASSEMBLY_PATH
                Me.SelKey(enmUN.app_folder).Contents = flnASSEMBLY_FOLDER

                'enmUN.compiler_exe, enmUN.path take the first non-prefixed parameters; they are just file paths but without /parameter_name=
                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText, enmUN.compiler_exe, enmUN.path)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function 'InsFrom_Application

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCboard(ur_hdr As Boolean) As Integer
                ToCboard = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN

VBNetCode\Version

<<ext "WestWindCom Net Core Runtime">>
<<ext "SO.com RunTime Net 4.5">>

```
Function version_info() As String
version_info = "flag CLR 4.5 Features = " & If(Type.GetType(typeName:="System.Reflection.ReflectionContext", throwOnError:=False) Is Nothing, "", "True") & vbCrLf
version_info &= "flag CLR 4.51 Features = " & If(Type.GetType(typeName:="System.Runtime.GCLargeObjectHeapCompactionMode", throwOnError:=False) Is Nothing, "", "True") & vbCrLf
version_info &= "CLR Version = " & System.Environment.Version.ToString & vbCrLf
version_info &= "CLR Local Path = " & System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() & vbCrLf
version_info &= "Operating System = " & CType(System.Attribute.GetCustomAttribute(System.Reflection.Assembly.GetEntryAssembly(), GetType(System.Runtime.Versioning.TargetFrameworkAttribute)), System.Runtime.Versioning.TargetFrameworkAttribute).FrameworkName & " on " & System.Runtime.InteropServices.RuntimeInformation.OSDescription
End Function
```

VBNetProject

DOC
<<glbl_article_list>>

VBNetProject\~Clear Local

WindowsCLI CodeLibrary VBCode
```
rd /s /q bin
rd /s /q obj
pause

VBNetProject\~Rebiuld Local

CodeLibrary Extract VBCode
```
for %%f in (*.sln) do (
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
	
    for /D %%m in ("C:\Program Files (x86)\MSBuild\*\Bin\MSBuild.exe") do (
        "%%~m" /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
    
    for %%m in ("C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe") do (
        %%m /v:n /p:Configuration=Release "%%f"
        goto :compile_complete
       )
   )
:compile_complete
pause
del ..\Dep\*.exe
move bin\Release\*.exe ..\Dep
rd /s /q bin
rd /s /q obj
pause

VBNetProject\dbUserInputMock

CodeLibrary VBCode
!! Automatically convert the form to the dbUserInput class

```
Partial Public Class frmInput_1
    <System.Diagnostics.DebuggerHidden()>
    Public Shared Widening Operator CType(b As frmInput_1) As Mx.dbUserInput
        Return New Mx.dbUserInput(b, b.txtNotice_Message)
    End Operator
End Class 'frmInput_1
```

!! Setup the mock classes
* Create flat classes that have the desired values

```
Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock
End Namespace 'Mx2
```

* In a copy of the Mx.dbUserInput class, rename every `System.Windows.Forms` reference to `Mx2.Mock`

```
Option Strict On
Namespace Mx
    Public Class componentTextBox
        Private objTEXT_BOX As System.Windows.Forms.TextBox

        Public Sub New(ur_textbox As System.Windows.Forms.TextBox)
            objTEXT_BOX = ur_textbox
        End Sub

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objTEXT_BOX IsNot Nothing Then
                    Text = objTEXT_BOX.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objTEXT_BOX IsNot Nothing Then
                    objTEXT_BOX.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'componentTextBox

    Public Class dbUserInput
        Private objINPUT_FORM As System.Windows.Forms.Form
        Public txtNotice_Message As componentTextBox

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_input_form As System.Windows.Forms.Form, ur_notice_message_textbox As System.Windows.Forms.TextBox)
            objINPUT_FORM = ur_input_form
            Me.txtNotice_Message = New componentTextBox(ur_notice_message_textbox)
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Close()
            If objINPUT_FORM IsNot Nothing Then
                objINPUT_FORM.Close()
            End If
        End Sub

        Public Property BackColor As System.Drawing.Color
            <System.Diagnostics.DebuggerHidden()>
            Get
                BackColor = Nothing
                If objINPUT_FORM IsNot Nothing Then
                    BackColor = objINPUT_FORM.BackColor
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As System.Drawing.Color)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.BackColor = value
                End If
            End Set
        End Property 'BackColor

        Public Property Text As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                Text = mt
                If objINPUT_FORM IsNot Nothing Then
                    Text = objINPUT_FORM.Text
                End If
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(value As String)
                If objINPUT_FORM IsNot Nothing Then
                    objINPUT_FORM.Text = value
                End If
            End Set
        End Property 'Text
    End Class 'dbUserInput
End Namespace 'Mx
```

!! Create sample data
* Load the mock dbUserInput with the testing state

```
Dim mockTextBox = New Mock.TextBox
Dim mockForm = New Mock.Form
Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
Call Mx.UserAction.Run_Script_errhnd(mockUserInput)
```

* Compare the mock dbUserInput field changes to the expected result state

```
Dim strFOUND_RESULT = mockTextBox.Text
If strFOUND_RESULT = strEXPECTED_RESULT Then
	intPASS_COUNT += 1

Else
	intFAIL_COUNT += 1
	stpMOCK_REPORT.dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`").dLine())
End If 'strFOUND_RESULT
```

VBNetProject\DeveloperSettings

CodeLibrary VBCode
<<ext "DeveloperSettings HTM"">>

<<ext "DeveloperSettings ZIP"">>

VBNetProject\MxBaseEc13

CodeLibrary VBCode
<<ext "MxBase Classes">>

```
Option Strict On
Namespace Mx '2020m01d03
    Public Module ConstVar
        Public Const mt = ""
        Public Const qs = """"
        Public Const qt = "'"
        Public Const s = " "

        <System.Diagnostics.DebuggerHidden()>
        Public Function AreEqual(ur_val As String, ur_cmp As String) As Boolean
            AreEqual = String.Equals(ur_val, ur_cmp, System.StringComparison.CurrentCultureIgnoreCase)
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b0(ur_val As Integer) As Integer
            b0 = ur_val - 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function b1(ur_val As Integer) As Integer
            b1 = ur_val + 1
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function ContainingText(ur_large_text As String, ur_small_text As String) As Boolean
            ContainingText = InStr(ur_large_text, ur_small_text, CompareMethod.Text) > 0
        End Function 'ContainingText
        <System.Diagnostics.DebuggerHidden()>
        Public Function gUTF8_FileEncoding() As System.Text.UTF8Encoding
            gUTF8_FileEncoding = glbl.gUTF8_Encoding
        End Function
        <System.Diagnostics.DebuggerHidden()>
        Public Function EndingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            EndingWithText = AreEqual(Right(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'EndingWithText
        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText(ur_value As String) As Boolean
            HasText = Not String.IsNullOrWhiteSpace(ur_value)
        End Function 'HasText
        <System.Diagnostics.DebuggerHidden()>
        Public Function StartingWithText(ur_large_text As String, ur_small_text As String) As Boolean
            StartingWithText = AreEqual(Left(ur_large_text, Len(ur_small_text)), ur_small_text)
        End Function 'StartingWithText

        <System.Diagnostics.DebuggerHidden()>
        Public Function CmdOutput(ur_exec_path As String, Optional ur_exec_param As String = mt) As String
            Dim objPCS As New System.Diagnostics.Process()
            With 1 : Dim prcINFO = objPCS.StartInfo
                prcINFO.FileName = ur_exec_path
                prcINFO.Arguments = ur_exec_param
                prcINFO.UseShellExecute = False
                prcINFO.RedirectStandardOutput = True
                prcINFO.CreateNoWindow = True
            End With 'prcINFO

            objPCS.Start()
            CmdOutput = objPCS.StandardOutput.ReadToEnd()
            objPCS.WaitForExit()
        End Function 'CmdOutput

        <System.Diagnostics.DebuggerHidden()>
        Public Function FileNamed() As MxText.FileName
            FileNamed = New MxText.FileName
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Strapd() As Strap
            Strapd = New Strap
        End Function

        Public Class glbl
            Private Shared objUTF8_ENCODING As System.Text.UTF8Encoding

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If objUTF8_ENCODING Is Nothing Then
                    objUTF8_ENCODING = New System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier:=False, throwOnInvalidBytes:=True)
                End If
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function gUTF8_Encoding() As System.Text.UTF8Encoding
                Call glbl.Init()
                gUTF8_Encoding = glbl.objUTF8_ENCODING
            End Function
        End Class 'glbl
    End Module 'ConstVar

    Public Class ErrListBase
        Dim pstpNOTICE_MSG As Strap

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            pstpNOTICE_MSG = Strapd()
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Function DoContinue() As Boolean
            DoContinue = (Me.Found = False)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            If pstpNOTICE_MSG.Length > 0 Then
                pstpNOTICE_MSG.dLine().dLine()
            End If

            pstpNOTICE_MSG.dLine(ur_exception.Message)
            pstpNOTICE_MSG.dLine(Strapd().d("Error in @r1.@r2").r1(ur_methodbase.DeclaringType.Name).r2(ur_methodbase.Name).dS("(status: @r1)").r1(ur_procedure_status))
        End Sub 'dError_Data

        <System.Diagnostics.DebuggerHidden()>
        Public Sub dError_Stack(ur_exception As System.Exception)
            Dim hr As Integer = System.Runtime.InteropServices.Marshal.GetHRForException(ur_exception)
            pstpNOTICE_MSG.dLine(ur_exception.GetType.ToString & "(0x" & hr.ToString("X8") & "): " & ur_exception.Message & System.Environment.NewLine & ur_exception.StackTrace & System.Environment.NewLine)
            Dim st = New System.Diagnostics.StackTrace(ur_exception, True)
            For Each objFRAME In st.GetFrames
                If objFRAME.GetFileLineNumber() > 0 Then
                    pstpNOTICE_MSG.dLine("Line:" & objFRAME.GetFileLineNumber() & " Filename: " & System.IO.Path.GetFileName(objFRAME.GetFileName) & System.Environment.NewLine)
                End If
            Next objFRAME
        End Sub 'dError_Stack

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function Found() As Boolean
            Found = (pstpNOTICE_MSG.Length > 0)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = pstpNOTICE_MSG
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Sub Throw_Error_Data(ur_exception As System.Exception, ur_methodbase As System.Reflection.MethodBase, Optional ur_procedure_status As String = mt)
            Call Me.dError_Data(ur_exception, ur_methodbase, ur_procedure_status)
            Throw New LocalException(mt)
        End Sub 'Throw_Error_Data


        Public Class LocalException
            Inherits System.Exception

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String)
                MyBase.New(message)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(message As String, inner As System.Exception)
                MyBase.New(message, inner)
            End Sub
        End Class 'LocalException
    End Class 'ErrListBase

    Public Class iWrap(Of T)
        Public v As T

        Public Sub New(ur_t As T)
            Me.v = ur_t
        End Sub
    End Class 'iWrap

    Public Class ObaCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Obalist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list As Obalist(Of T) = Nothing)
            Call MyBase.New(prv.TotalItems(ur_list))
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObaCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property v() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObaCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function TotalItems(Optional ur_list As Obalist(Of T) = Nothing) As Integer
                TotalItems = 0
                If ur_list IsNot Nothing Then
                    TotalItems = ur_list.Count
                End If
            End Function 'TotalItems
        End Class 'prv
    End Class 'ObaCTR

    Public Class ObjCTR(Of T)
        Inherits RCTR

        Private vsdaLIST As Objlist(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_list As Objlist(Of T))
            Call MyBase.New(ur_list.Count)
            Me.vsdaLIST = ur_list
        End Sub

        Public Shadows ReadOnly Property Current() As ObjCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        Public Shadows ReadOnly Property row() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                row = Me.vsdaLIST.Item(Me.Indexenm)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As ObjCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function
    End Class 'ObjCTR

    Public Class Obalist(Of T)
        Private vobjLIST() As T

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_list() As T = Nothing)
            Me.vobjLIST = ur_list
        End Sub

        Public ReadOnly Property Count() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Count = Me.vobjLIST.Length
            End Get
        End Property

        Public Property Item(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                Item = Me.vobjLIST(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.vobjLIST(ur_index) = ur_val
            End Set
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function kvp() As ObaCTR(Of T)
            kvp = New ObaCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Obalist

    Public Class Objlist(Of T)
        Inherits System.Collections.Generic.List(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As ObjCTR(Of T)
            kvp = New ObjCTR(Of T)(Me)
        End Function

        Public Property tr_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property tr_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                tr_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Objlist

    Public Class SDPCTR(Of T As {New})
        Inherits RCTR

        Private vsdpLIST As SdPair(Of T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdplist As SdPair(Of T))
            Call MyBase.New(ur_sdplist.Count)
            Me.vsdpLIST = ur_sdplist
        End Sub

        Public Shadows ReadOnly Property Current() As SDPCTR(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDPCTR(Of T)
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property l() As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = Me.vsdpLIST.l_enm(Me.Indexenm)
            End Get
        End Property

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.vsdpLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDPCTR

    Public Class SdPair(Of T As {New})
        Inherits Sdata
        Private vobjT As System.Collections.Generic.Dictionary(Of String, T)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            vobjT = New System.Collections.Generic.Dictionary(Of String, T)
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function d(ur_val As String, ur_link As T) As SdPair(Of T)
            d = Me
            Call Me.Add(ur_val)
            Call vobjT.Add(ur_val, ur_link)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDPCTR(Of T)
            kvp = New SDPCTR(Of T)(Me)
        End Function

        Public Property l(ur_key As String) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l = vobjT.Item(ur_key)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(ur_key) = ur_val
            End Set
        End Property

        Public Property l_b1(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_b1 = vobjT.Item(Me.v_b1(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_b1(ur_index)) = ur_val
            End Set
        End Property

        Public Property l_enm(ur_index As Integer) As T
            <System.Diagnostics.DebuggerHidden()>
            Get
                l_enm = vobjT.Item(Me.v_enm(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As T)
                vobjT.Item(Me.v_enm(ur_index)) = ur_val
            End Set
        End Property
    End Class 'SdPair

    Public Class RCTR
        Private pintMAX_NUM As Integer
        Private pintCUR_NUM As Integer

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(ByVal b As RCTR) As Integer
            Return b.Indexb1
        End Operator 'CType

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_max_num As Integer)
            Me.pintMAX_NUM = ur_max_num
        End Sub

        Public Shadows ReadOnly Property Current() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me.pintCUR_NUM
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function GetEnumerator() As RCTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public ReadOnly Property Indexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexb1 = Me.pintCUR_NUM
            End Get
        End Property

        Public ReadOnly Property Indexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Indexenm = b0(Me.pintCUR_NUM)
            End Get
        End Property

        Public ReadOnly Property LastIndexb1() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexb1 = Me.pintMAX_NUM
            End Get
        End Property

        Public ReadOnly Property LastIndexenm() As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                LastIndexenm = b0(Me.pintMAX_NUM)
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function MoveNext() As Boolean
            MoveNext = (Me.pintCUR_NUM < Me.pintMAX_NUM)
            Me.pintCUR_NUM += 1
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function Reset() As RCTR
            Reset = Me
            Me.pintCUR_NUM = 0
        End Function
    End Class 'RCTR

    Public Class SDACTR
        Inherits RCTR

        Private psdaLIST As Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_sdata As Sdata)
            Call MyBase.New(ur_sdata.Count)
            Me.psdaLIST = ur_sdata
        End Sub

        Public Shadows ReadOnly Property Current() As SDACTR
            <System.Diagnostics.DebuggerHidden()>
            Get
                Current = Me
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function GetEnumerator() As SDACTR
            GetEnumerator = Me
            Call Me.Reset()
        End Function

        Public Shadows ReadOnly Property v() As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.psdaLIST.v_enm(Me.Indexenm)
            End Get
        End Property
    End Class 'SDACTR

    Public Class Sdata
        Inherits System.Collections.Generic.List(Of String)

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_val As String) As Sdata
            d = Me
            Call Me.Add(ur_val)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ParamArray ur_val() As String) As Sdata
            dList = Me
            If ur_val IsNot Nothing Then
                For Each strENTRY In ur_val
                    If strENTRY Is Nothing Then
                        strENTRY = mt
                    End If

                    Call Me.Add(strENTRY)
                Next strENTRY
            End If
        End Function 'dList

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As Sdata
            gCopy = New Sdata().dList(Me.ToArray)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function kvp() As SDACTR
            kvp = New SDACTR(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Split(ur_text As String, ur_sprtr As Char) As Sdata
            Dim sdaCMP = New Sdata
            Split = sdaCMP
            For Each strTEXT In ur_text.Split(ur_sprtr)
                sdaCMP.Add(strTEXT)
            Next
        End Function 'Split

        Public Property v_b1(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_b1 = Me.Item(b0(ur_index))
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(b0(ur_index)) = ur_val
            End Set
        End Property

        Public Property v_enm(ur_index As Integer) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v_enm = Me.Item(ur_index)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = mt
                End If

                Me.Item(ur_index) = ur_val
            End Set
        End Property
    End Class 'Sdata

    Public Class Strap
        Private pstbTEXT As System.Text.StringBuilder

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            Me.pstbTEXT = New System.Text.StringBuilder
        End Sub

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Widening Operator CType(b As Strap) As String
            Return b.ToString
        End Operator

        <System.Diagnostics.DebuggerHidden()>
        Public Function Clear() As Strap
            Clear = Me
            Call Me.pstbTEXT.Clear()
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function d(ur_text As String) As Strap
            d = Me.dSprtr(mt, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSV_Quoted(ur_index_b1 As Integer, ur_text As String) As Strap
            dCSV_Quoted = Me
            If ur_index_b1 > 1 Then
                Me.d(",")
            End If

            Me.d(qs).d(ur_text.Replace(qs, qs & qs)).d(qs)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dList(ur_sprtr As String, ParamArray ur_text() As String) As Strap
            dList = Me
            If ur_text IsNot Nothing Then
                For Each strENTRY In ur_text
                    Call Me.dSprtr(ur_sprtr, strENTRY)
                Next strENTRY
            End If
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dCSVList(ParamArray ur_text() As String) As Strap
            dCSVList = Me
            If ur_text IsNot Nothing Then
                For ENTCTR = 0 To UBound(ur_text)
                    Me.dCSV_Quoted(ENTCTR + 1, ur_text(ENTCTR))
                Next ENTCTR
            End If
        End Function 'dCSVList

        <System.Diagnostics.DebuggerHidden()>
        Public Function dLine(Optional ur_text As String = "") As Strap
            dLine = Me.dSprtr(vbCrLf, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dS(ur_text As String) As Strap
            dS = Me.dSprtr(s, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function dSprtr(ur_sprtr As String, ur_text As String) As Strap
            dSprtr = Me
            Me.pstbTEXT.Append(ur_sprtr).Append(ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function gCopy(ur_text As String) As Strap
            gCopy = New Strap().d(Me)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function HasText() As Boolean
            HasText = (Me.Length > 0)
        End Function

        Public ReadOnly Property Length As Integer
            <System.Diagnostics.DebuggerHidden()>
            Get
                Length = Me.pstbTEXT.Length
            End Get
        End Property

        <System.Diagnostics.DebuggerHidden()>
        Public Function r1(ur_text As String) As Strap
            r1 = Me
            Call Me.pstbTEXT.Replace("@r1", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function r2(ur_text As String) As Strap
            r2 = Me
            Call Me.pstbTEXT.Replace("@r2", ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function rx(ur_index As Integer, ur_text As String) As Strap
            rx = Me
            Call Me.pstbTEXT.Replace("@r" & ur_index, ur_text)
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function ToString() As String
            ToString = Me.pstbTEXT.ToString
        End Function
    End Class 'Strap

    Public Class bitBASE
        Public name As String
        Public seq As Integer
    End Class

    Public Class TRow(Of T As {New, bitBASE})
        Inherits Sdata

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New()
            For Each intVAL In Me.RefColNames
                Me.Add(mt)
            Next
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function Index_TableSplit(ur_table As Objlist(Of TRow(Of T)), ur_key As T) As SdPair(Of Objlist(Of TRow(Of T)))
            Dim sdpRET = New SdPair(Of Objlist(Of TRow(Of T)))
            Index_TableSplit = sdpRET
            Dim tblCHUNK As Objlist(Of TRow(Of T)) = Nothing
            For Each rowCHUNK In ur_table
                Dim strINDEX = rowCHUNK.v(ur_key)
                Dim intFOUND = sdpRET.IndexOf(strINDEX)
                If intFOUND < 0 Then
                    tblCHUNK = New Objlist(Of TRow(Of T))
                    sdpRET.d(strINDEX, tblCHUNK)
                Else
                    tblCHUNK = sdpRET.l_enm(intFOUND)
                End If

                tblCHUNK.Add(rowCHUNK)
            Next rowCHUNK

            Call sdpRET.Sort()
        End Function 'Index_TableSplit


        <System.Diagnostics.DebuggerHidden()>
        Public Shadows Function gCopy() As TRow(Of T)
            Dim sdaRET = New TRow(Of T)
            gCopy = sdaRET
            For Each kvpENTRY In Me.kvp
                sdaRET.v_enm(kvpENTRY.Indexenm) = kvpENTRY.v
            Next kvpENTRY
        End Function

        Public Function Link_Table(ur_table As Objlist(Of TRow(Of T)), ParamArray ur_key_list() As T) As Objlist(Of TRow(Of T))
            Dim tblRET = New Objlist(Of TRow(Of T))
            Link_Table = tblRET
            For Each rowCHUNK In ur_table
                Dim bolFOUND = True
                For Each intKEY In ur_key_list
                    If AreEqual(rowCHUNK.v(intKEY), Me.v(intKEY)) = False Then
                        bolFOUND = False
                        Exit For
                    End If
                Next intKEY

                If bolFOUND Then
                    tblRET.Add(rowCHUNK)
                End If
            Next rowCHUNK
        End Function 'Link_Table

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function PersistRead(ur_persist_path As String) As Objlist(Of TRow(Of T))
            Dim ttbRET = New Objlist(Of TRow(Of T))
            PersistRead = ttbRET
            If Mx.glbl.gWindowsFS.HasFile(ur_persist_path) Then
                Dim bolFIRST_LINE = True
                Dim lstREF_COL = New Objlist(Of T)
                Using stmIN_FILE = Mx.glbl.gWindowsFS.ReadStream(ur_persist_path)
                    Dim strLINE = mt
                    While stmIN_FILE.EndOfStream = False
                        strLINE &= stmIN_FILE.ReadLine
                        Dim bolBALANCED_QUOTES = True
                        For CHRCTR = 0 To strLINE.Length - 1
                            If strLINE(CHRCTR) = """"c Then
                                bolBALANCED_QUOTES = Not bolBALANCED_QUOTES
                            End If
                        Next CHRCTR

                        If bolBALANCED_QUOTES = False Then
                            strLINE &= vbCrLf

                        Else
                            Dim new_row = New TRow(Of T)
                            If Left(strLINE, 1) = vbLf Then
                                strLINE = Mid(strLINE, 2)
                            End If

                            If bolFIRST_LINE = True Then
                                bolFIRST_LINE = False
                                Dim bolCOL_MATCH = False
                                Dim sdaFIRST_ROW = MxText.CSVSplit(strLINE, vbTab)
                                For Each strENTRY In MxText.CSVSplit(strLINE, vbTab)
                                    Dim enmFOUND_KEY As T = Nothing
                                    For Each enmKEY In new_row.RefColKeys
                                        If AreEqual(enmKEY.name, strENTRY) Then
                                            enmFOUND_KEY = enmKEY
                                            bolCOL_MATCH = True
                                            Exit For
                                        End If
                                    Next enmKEY

                                    lstREF_COL.Add(enmFOUND_KEY)
                                Next strENTRY

                                If bolCOL_MATCH = False Then
                                    Exit While
                                End If

                            ElseIf HasText(strLINE) Then
                                For Each kvpCOL In MxText.CSVSplit(strLINE, vbTab).kvp
                                    Dim enmKEY = lstREF_COL.Item(kvpCOL.Indexenm)
                                    If enmKEY IsNot Nothing Then
                                        new_row.v(enmKEY) = kvpCOL.v
                                    End If
                                Next kvpCOL

                                ttbRET.Add(new_row)
                            End If 'bolFIRST_LINE

                            strLINE = mt
                        End If 'bolBALANCED_QUOTES
                    End While
                End Using 'stmIN_FILE
            End If 'ur_persist_path
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Sub PersistWrite(ur_table As Objlist(Of TRow(Of T)), ur_persist_path As MxText.FileName)
            If Mx.glbl.gWindowsFS.HasDir(ur_persist_path.gParentDir) = False Then
                Mx.glbl.gWindowsFS.CreateDirectory(ur_persist_path.gParentDir)
            End If

            Using stmOUT_FILE = Mx.glbl.gWindowsFS.WriteStream(ur_persist_path)
                For Each kvpROW In ur_table.kvp
                    stmOUT_FILE.Write(kvpROW.row.ToString(kvpROW.Indexb1 = 1, True))
                Next
            End Using 'stmOUT_FILE
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeys() As Objlist(Of T)
            RefColKeys = TRow(Of T).glbl.RefKeys
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColKeySearch(ur_name As String) As Objlist(Of T)
            RefColKeySearch = TRow(Of T).glbl.RefKeySearch(ur_name)
        End Function 'RefColKeySearch

        <System.Diagnostics.DebuggerHidden()>
        Public Function RefColNames() As Sdata
            RefColNames = TRow(Of T).glbl.RefNames
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ToCbrd(ur_hdr As Boolean) As Integer
            ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean, Optional ur_quoted As Boolean = False) As Strap
            Dim stpRET = New Strap
            ToString = stpRET
            If ur_hdr Then : For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : stpRET.d(kvpCOL.v) : Next kvpCOL : stpRET.dLine() : End If
            For Each kvpCOL In Me.RefColNames.kvp : If kvpCOL.Indexb1 > 1 Then : stpRET.d(vbTab) : End If : If ur_quoted Then : stpRET.d(qs).d(Me.v_enm(kvpCOL.Indexenm).Replace(qs, qs & qs)).d(qs) : Else : stpRET.d(Me.v_enm(kvpCOL.Indexenm)) : End If : Next kvpCOL : stpRET.dLine()
        End Function


        Public Property v(ur_cl As T) As String
            <System.Diagnostics.DebuggerHidden()>
            Get
                v = Me.Item(ur_cl.seq)
            End Get
            <System.Diagnostics.DebuggerHidden()>
            Set(ur_val As String)
                If ur_val Is Nothing Then
                    ur_val = ""
                End If

                Me.Item(ur_cl.seq) = ur_val
            End Set
        End Property

        Public Class glbl
            Private Shared sdaTCOL_NAME As Sdata
            Private Shared sdjTCOL_KEY As Objlist(Of T)

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub Init()
                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME Is Nothing Then
                    Dim objTEST = GetType(T).GetFields()(0).GetValue(Nothing)
                End If

                If sdjTCOL_KEY Is Nothing AndAlso
                  sdaTCOL_NAME IsNot Nothing Then
                    sdjTCOL_KEY = New Objlist(Of T)
                    Dim tpeCMP = GetType(T)
                    For Each kvpCOL In sdaTCOL_NAME.kvp
                        For Each objPROP In tpeCMP.GetFields()
                            If tpeCMP.DeclaringType Is tpeCMP Then
                                Dim objBIT = DirectCast(objPROP.GetValue(Nothing), bitBASE)
                                If objBIT.seq = kvpCOL.Indexenm Then
                                    sdjTCOL_KEY.Add(DirectCast(objPROP.GetValue(Nothing), T))
                                    Exit For
                                End If
                            End If 'tpeCMP
                        Next objPROP
                    Next kvpCOL
                End If 'sdaTCOL_NAME
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Function NewProp() As T
                Dim objRET = New T
                NewProp = objRET

                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            objRET.name = objPROP.Name
                            objRET.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(objRET.name)
                            sdjTCOL_KEY.Add(objRET)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Function 'NewProp

            <System.Diagnostics.DebuggerHidden()>
            Private Shared Sub NewProp(ur_prop As T)
                If sdaTCOL_NAME Is Nothing Then
                    sdaTCOL_NAME = New Sdata
                    sdjTCOL_KEY = New Objlist(Of T)
                End If

                Dim intNEXT_SEQ = sdaTCOL_NAME.Count
                Dim tpeB = GetType(T)
                For Each objPROP In tpeB.GetFields()
                    If objPROP.DeclaringType Is tpeB Then
                        Dim objFOUND = objPROP.GetValue(Nothing)
                        If objFOUND Is Nothing Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        ElseIf objFOUND.GetType.DeclaringType Is tpeB AndAlso
                          sdaTCOL_NAME.Contains(objPROP.Name) = False Then
                            ur_prop.name = objPROP.Name
                            ur_prop.seq = intNEXT_SEQ
                            sdaTCOL_NAME.Add(ur_prop.name)
                            sdjTCOL_KEY.Add(ur_prop)
                            Exit For
                        End If 'objFOUND
                    End If
                Next objPROP
            End Sub 'Init

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function NewBitBase() As T
                NewBitBase = glbl.NewProp()
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub NewBitBase(ur_prop As T)
                Call glbl.NewProp(ur_prop)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeys() As Objlist(Of T)
                Call glbl.Init()
                RefKeys = glbl.sdjTCOL_KEY
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefKeySearch(ur_name As String) As Objlist(Of T)
                Call glbl.Init()
                Dim ttbRET = New Objlist(Of T)
                RefKeySearch = ttbRET
                Dim intFOUND_INDEX = TRow(Of T).glbl.RefNames.IndexOf(ur_name)
                If intFOUND_INDEX >= b0(1) Then
                    ttbRET.Add(TRow(Of T).glbl.RefKeys(intFOUND_INDEX))
                End If
            End Function 'RefKeySearch

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function RefNames() As Sdata
                Call glbl.Init()
                RefNames = glbl.sdaTCOL_NAME
            End Function

            Public Class Trbase(Of W As {New, T})
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function NewBitBase() As W
                    Dim objRET = New W
                    NewBitBase = objRET
                    Call TRow(Of T).glbl.NewBitBase(objRET)
                End Function
            End Class 'Trbase
        End Class 'glbl
    End Class 'Trow

    Partial Public Class MxText 'Parse
        Public Class enmCMD_RET
            Inherits bitBASE
            Public Shared eq As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared fslash As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared qs_end As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared txt As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared unk As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
            Public Shared ws As enmCMD_RET = TRow(Of enmCMD_RET).glbl.NewBitBase()
        End Class

        Public Class Cmdline_UB(Of T As {New, bitBASE}, W As {New, bitBASE})
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                CommandLine_UBParm = prv.CommandLine_UBParm(ur_ub_key, ur_ub_val, ur_source_text, ur_default_field_list)
            End Function

            Class sCMDLINE
                Inherits Mx.Objlist(Of TRow(Of enmCMD_RET))

                <System.Diagnostics.DebuggerHidden()>
                Public Overloads Function ToString(ur_hdr As Boolean) As String
                    Dim stpRET = Strapd() : For Each kvpREC In Me.kvp : stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr)) : Next kvpREC : ToString = stpRET
                End Function 'ToString
                <System.Diagnostics.DebuggerHidden()>
                Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                End Function
            End Class 'sCMDLINE

            Class sCMD_RET
                Public ttbUB_PARM As Objlist(Of TRow(Of W))
                Public ttbCMD_PARM As sCMDLINE
            End Class

            Partial Private Class prv
                <System.Diagnostics.DebuggerHidden()>
                Public Shared Function CommandLine_UBParm(ur_ub_key As W, ur_ub_val As W, ur_source_text As String, ParamArray ur_default_field_list() As T) As sCMD_RET
                    Dim objRET = New sCMD_RET
                    CommandLine_UBParm = objRET
                    objRET.ttbUB_PARM = New Objlist(Of TRow(Of W))
                    objRET.ttbCMD_PARM = New sCMDLINE
                    Dim rowCMD_PARM = New TRow(Of enmCMD_RET)
                    objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                    Dim sdaDEFAULT_PARMNAME = New Sdata
                    Dim sdaDEST_PARMS = TRow(Of T).glbl.RefNames
                    For Each intUN In ur_default_field_list
                        sdaDEFAULT_PARMNAME.d(intUN.name)
                    Next

                    Dim stpCOMPILE = Strapd()
                    Dim intPREV_CHUNK = enmCMD_RET.ws
                    Dim intCHUNK_C = enmCMD_RET.ws
                    For CHRCTR = 0 To ur_source_text.Length - 1
                        Dim chrC = ur_source_text(CHRCTR)
                        intCHUNK_C = gChunkType(chrC)
                        Dim intSPAN = 1
                        For SPNCTR = CHRCTR + 1 To ur_source_text.Length - 1
                            Dim chrS = ur_source_text(SPNCTR)
                            Dim intSPAN_C = gChunkType(chrS)
                            If intSPAN_C IsNot intCHUNK_C OrElse
                              intSPAN_C Is enmCMD_RET.qs Then
                                'Combine all chunks except for escaped quotes
                                intSPAN = SPNCTR - CHRCTR
                                Exit For
                            End If

                            If SPNCTR = ur_source_text.Length - 1 Then
                                intSPAN = SPNCTR + 1 - CHRCTR
                                Exit For
                            End If
                        Next SPNCTR

                        Dim strCHUNK = ur_source_text.Substring(CHRCTR, intSPAN)
                        If intPREV_CHUNK Is enmCMD_RET.ws Then
                            'Have ws, skip compiled ws; wait for fslash or default parm
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'skip compiled fslash
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip ws between parameters

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'compile unquoted default parameter
                                rowCMD_PARM.v(enmCMD_RET.fslash) = mt
                                If sdaDEFAULT_PARMNAME.Count > 0 Then
                                    rowCMD_PARM.v(enmCMD_RET.fslash) = sdaDEFAULT_PARMNAME.v_b1(1)
                                    sdaDEFAULT_PARMNAME.RemoveAt(b0(1))
                                End If

                                intPREV_CHUNK = enmCMD_RET.txt
                                stpCOMPILE.Clear.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.fslash Then
                            'Have ws-fslash, compile txt parm name; wait for eq
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'qs between parm name and eq is unk
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq Then
                                'skip compile qe
                                rowCMD_PARM.v(enmCMD_RET.fslash) = stpCOMPILE.ToString
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = enmCMD_RET.eq

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'compile txt into parm name
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.eq Then
                            'Have ws-fslash-eq, skip compile; wait for txt
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'flush parameter as "=true"; start new parameter
                                stpCOMPILE.Clear.d("true")
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'skip qs around quoted parameter value
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'keep ws in eq

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'skip eq between paramater name and value

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                'store param name, compile unquoted parameter value
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.txt Then
                            'Have ws-fslash-eq-txt, compile parm val; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                'Keep fslash and qs in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq Then
                                'Keep eq in unquoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs Then
                            'Have ws-fslash-eq-qs, compile parm val; wait for qs_end
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'Keep fslash in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'hold parameter; skip this qs and look for another escaped qs or flush the parameter
                                intPREV_CHUNK = enmCMD_RET.qs_end

                            ElseIf intCHUNK_C Is enmCMD_RET.ws OrElse
                              intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'Keep ws, eq and txt in quoted param value
                                stpCOMPILE.d(strCHUNK)

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.qs_end Then
                            'Have ws-fslash-eq-qs-qsend, compile parm val without ending quote; wait for qs or ws
                            If intCHUNK_C Is enmCMD_RET.fslash Then
                                'qs_end then fslash without ws between is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            ElseIf intCHUNK_C Is enmCMD_RET.qs Then
                                'keep escaped qs
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'flush parameter; start new parameter
                                Dim objFLUSH = prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)
                                rowCMD_PARM = objFLUSH.rowCMD_PARM
                                intPREV_CHUNK = objFLUSH.intPREV_CHUNK

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                'qs_end then ws or txt is unk
                                stpCOMPILE.d(strCHUNK)
                                intPREV_CHUNK = enmCMD_RET.unk

                            End If

                        ElseIf intPREV_CHUNK Is enmCMD_RET.unk Then
                            'Have unk, skip compile; wait for ws
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse
                              intCHUNK_C Is enmCMD_RET.qs Then
                                stpCOMPILE.d(strCHUNK)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip parameter; start new parameter
                                rowCMD_PARM.v(enmCMD_RET.txt) = stpCOMPILE.ToString
                                rowCMD_PARM = New TRow(Of enmCMD_RET)
                                objRET.ttbCMD_PARM.Add(rowCMD_PARM)
                                stpCOMPILE.Clear()
                                intPREV_CHUNK = intCHUNK_C

                            ElseIf intCHUNK_C Is enmCMD_RET.eq OrElse
                              intCHUNK_C Is enmCMD_RET.txt Then
                                stpCOMPILE.d(strCHUNK)
                            End If
                        End If

                        CHRCTR += intSPAN - 1

                        If CHRCTR = ur_source_text.Length - 1 Then
                            'On last entry
                            If intCHUNK_C Is enmCMD_RET.fslash OrElse intCHUNK_C Is enmCMD_RET.eq Then
                                'flush default parameter value
                                stpCOMPILE.Clear.d("true")
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.qs OrElse intCHUNK_C Is enmCMD_RET.txt Then
                                'flush parameter
                                Call prv.Flush_Parameter(ur_ub_key, ur_ub_val, rowCMD_PARM, stpCOMPILE, intCHUNK_C, sdaDEST_PARMS, objRET)

                            ElseIf intCHUNK_C Is enmCMD_RET.ws Then
                                'skip trailing ws
                            End If
                        End If
                    Next CHRCTR
                End Function 'CommandLine_Chunk

                Private Class Flush_Ret
                    Public rowCMD_PARM As TRow(Of enmCMD_RET)
                    Public intPREV_CHUNK As enmCMD_RET
                End Class

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function Flush_Parameter(ur_ub_key As W, ur_ub_val As W, ur_cmdparm_row As TRow(Of enmCMD_RET), ur_parm_val As Strap, ur_new_prevchunk As enmCMD_RET, ur_refname_list As Sdata, ur_objret_arl As sCMD_RET) As Flush_Ret
                    Dim objRET = New Flush_Ret
                    Flush_Parameter = objRET
                    objRET.rowCMD_PARM = New TRow(Of enmCMD_RET)
                    ur_objret_arl.ttbCMD_PARM.Add(objRET.rowCMD_PARM)
                    objRET.intPREV_CHUNK = ur_new_prevchunk
                    'flush parameter
                    ur_cmdparm_row.v(enmCMD_RET.txt) = ur_parm_val
                    Dim intFOUND = ur_refname_list.IndexOf(ur_cmdparm_row.v(enmCMD_RET.fslash).ToLower)
                    If intFOUND >= 0 Then
                        With 1 : Dim sdaROW = New TRow(Of W)
                            sdaROW.v(ur_ub_key) = ur_refname_list.v_enm(intFOUND)
                            sdaROW.v(ur_ub_val) = ur_cmdparm_row.v(enmCMD_RET.txt)
                            ur_objret_arl.ttbUB_PARM.Add(sdaROW)
                        End With

                        'Skip parameter if not found
                    End If

                    ur_parm_val.Clear()
                End Function

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Function gChunkType(ur_char As Char) As enmCMD_RET
                    If ur_char = vbCr OrElse
                  ur_char = vbLf OrElse
                  ur_char = " "c OrElse
                  ur_char = vbTab Then
                        gChunkType = enmCMD_RET.ws

                    ElseIf ur_char = "="c OrElse
                  ur_char = ":"c Then
                        gChunkType = enmCMD_RET.eq

                    ElseIf ur_char = "/"c Then
                        gChunkType = enmCMD_RET.fslash

                    ElseIf ur_char = """"c Then
                        gChunkType = enmCMD_RET.qs

                    Else
                        gChunkType = enmCMD_RET.txt
                    End If
                End Function 'gChunkType
            End Class 'prv
        End Class
    End Class 'MxText-Parse

    Partial Public Class MxText
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function CSVSplit(ByVal ur_line As String, Optional ur_separator As String = ",") As Sdata
            Dim sdaCMP = New Sdata
            CSVSplit = sdaCMP
            Dim objARRAY = ur_line.ToCharArray
            Dim objSPRTR = Mid(ur_separator, 1, 1).ToCharArray()(0)
            Dim objESCAPE_QUOTE = """"c

            Const cstSTART = 0
            Const cstESC = 1
            Const cstQS = 2
            Dim intPARSE_STATE = cstSTART
            Dim intLEN = Len(ur_line) - 1
            Dim stpFIELD As New Strap
            For intIX = 0 To intLEN
                Dim objCHR = objARRAY(intIX)
                Select Case intPARSE_STATE
                    Case cstESC
                        stpFIELD.d(objCHR)
                        intPARSE_STATE = cstQS

                    Case cstQS
                        If objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstSTART
                            Dim intNEXT_IX = intIX + 1
                            If intNEXT_IX < intLEN Then
                                If objARRAY(intNEXT_IX) = objESCAPE_QUOTE Then
                                    intPARSE_STATE = cstESC
                                End If 'intNEXT_IX
                            End If 'intNEXT_IX

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR

                    Case cstSTART
                        If objCHR = objSPRTR Then
                            sdaCMP.d(stpFIELD.ToString)
                            Call stpFIELD.Clear()

                        ElseIf objCHR = objESCAPE_QUOTE Then
                            intPARSE_STATE = cstQS

                        Else 'objCHR
                            stpFIELD.d(objCHR)
                        End If 'objCHR
                End Select 'intPARSE_STATE
            Next intIX

            sdaCMP.d(stpFIELD)
        End Function 'CSVSplit
    End Class 'MxText-Csv

    Public Class MxText
        Public Class FileName
            Public FilePath As String
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.FilePath = mt
            End Sub 'New
            <System.Diagnostics.DebuggerHidden()>
            Public Sub New(ur_path As String)
                Me.FilePath = ur_path
            End Sub 'New

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As FileName) As String
                Return b.FilePath
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Widening Operator CType(b As String) As FileName
                Return New FileName(b)
            End Operator 'CType
            <System.Diagnostics.DebuggerHidden()>
            Public Shadows Function ToString() As String
                ToString = Me.FilePath
            End Function 'ToString

            <System.Diagnostics.DebuggerHidden()>
            Public Function dAppendEXT(ur_ext As String) As FileName
                dAppendEXT = Me
                If ur_ext.StartsWith(".") = False Then
                    ur_ext = "." & ur_ext
                End If

                Me.FilePath &= ur_ext
            End Function 'dAppendEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function d(ur_file_name As String) As FileName
                d = Me
                If HasText(Me.FilePath) Then
                    Me.FilePath = System.IO.Path.Combine(Me.FilePath, ur_file_name)

                Else 'Me
                    Me.FilePath = ur_file_name
                End If 'Me
            End Function 'd

            <System.Diagnostics.DebuggerHidden()>
            Public Function dNowTextYMDHMS(ur_file_name As String, Optional ur_separator As String = "_") As FileName
                dNowTextYMDHMS = Me
                Me.d(ur_file_name & ur_separator & Now().ToString("yyyy\mMM\dddthh\mmm\sss").Replace("P12", "N12").Replace("A12", "A00").ToLower)
            End Function 'dNowTextYMDHMS

            Public Property Ext() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Ext = System.IO.Path.GetExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wEXT(value)
                End Set
            End Property 'Ext

            Public ReadOnly Property ExtAll() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ExtAll = Strapd().dList(mt, Me.ExtList.ToArray)
                End Get
            End Property 'ExtAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function ExtList() As Sdata
                Dim sdaDESC = Sdata.Split(Me.FilePath, "."c)
                ExtList = sdaDESC
                sdaDESC.RemoveAt(0)
                For Each ROWCTR In sdaDESC.kvp
                    sdaDESC.v_b1(ROWCTR) = "." & sdaDESC.v_b1(ROWCTR)
                Next ROWCTR
            End Function 'ExtList

            Public Property FileGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileGroup = System.IO.Path.GetFileNameWithoutExtension(Me.FilePath)
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.Ext
                End Set
            End Property 'FileGroup

            Public Property FileBaseGroup() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    FileBaseGroup = mt
                    For Each strENTRY In Sdata.Split(Me.Name, "."c)
                        FileBaseGroup = strENTRY
                        Exit For
                    Next
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.Name = value & Me.ExtAll
                End Set
            End Property 'FileBaseGroup

            <System.Diagnostics.DebuggerHidden()>
            Public Function gCopy() As FileName
                gCopy = New FileName(Me)
            End Function 'gCopy

            <System.Diagnostics.DebuggerHidden()>
            Public Function gFullPath() As FileName
                gFullPath = New FileName(glbl.gWindowsFS.GetFullPath(Me.FilePath))
            End Function 'gFullPath

            <System.Diagnostics.DebuggerHidden()>
            Public Function gParentDir() As FileName
                gParentDir = New FileName(Me.ParentDir)
            End Function 'gParentDir

            Public Property Name() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Name = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If

                    If HasText(strPATH) Then
                        Name = System.IO.Path.GetFileName(strPATH)
                    End If
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.wParentDir.d(value)
                End Set
            End Property 'Name

            Public Property ParentDir() As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    ParentDir = mt
                    Dim strPATH = Me.FilePath
                    If HasText(strPATH) Then
                        If HasText(System.IO.Path.GetFileName(strPATH)) = False Then
                            strPATH = System.IO.Path.GetDirectoryName(strPATH)
                        End If 'strPATH
                    End If 'strPATH

                    If HasText(strPATH) Then
                        ParentDir = System.IO.Path.GetDirectoryName(strPATH)
                    End If 'strPATH
                End Get

                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Dim strFILE_NAME = Me.Name
                    If HasText(value) Then
                        Me.FilePath = System.IO.Path.Combine(value, strFILE_NAME)

                    Else 'value
                        Me.FilePath = strFILE_NAME
                    End If 'value
                End Set
            End Property 'ParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function ParentList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH = Me.PathList
                ParentList = sdaPATH
                sdaPATH.RemoveAt(b0(sdaPATH.Count))
            End Function 'ParentList

            <System.Diagnostics.DebuggerHidden()>
            Public Function PathList() As System.Collections.Generic.List(Of FileName)
                Dim sdaPATH As New System.Collections.Generic.List(Of FileName)
                PathList = sdaPATH

                Dim sdaDESC = New Objlist(Of FileName)
                sdaDESC.Add(Me.gCopy)
                Dim objREDUCE = Me.gCopy
                Call objREDUCE.wParentDir()
                While HasText(objREDUCE.FilePath)
                    sdaDESC.Add(objREDUCE.gCopy)
                    Call objREDUCE.wParentDir()
                End While 'objREDUCE

                For Each objFILE In sdaDESC
                    sdaPATH.Add(objFILE)
                Next objFILE
            End Function 'PathList

            <System.Diagnostics.DebuggerHidden()>
            Public Function wAssemblyDir(ur_assembly_info As Microsoft.VisualBasic.ApplicationServices.AssemblyInfo) As FileName
                wAssemblyDir = Me
                Me.FilePath = ur_assembly_info.DirectoryPath.Replace("\bin\Debug", mt)
            End Function 'wAssemblyDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wClear() As FileName
                wClear = Me
                Me.FilePath = mt
            End Function 'wClear

            <System.Diagnostics.DebuggerHidden()>
            Public Function wEXT(ur_ext As String) As FileName
                wEXT = Me
                Dim strFILE_NAME = Me.FileGroup
                If Left(ur_ext, 1) <> "." Then
                    ur_ext = "." & ur_ext
                End If 'ur_ext

                Me.wParentDir.d(strFILE_NAME & ur_ext)
            End Function 'wEXT

            <System.Diagnostics.DebuggerHidden()>
            Public Function wParentDir() As FileName
                wParentDir = Me
                Me.FilePath = Me.ParentDir
            End Function 'wParentDir

            <System.Diagnostics.DebuggerHidden()>
            Public Function wTempFileName(ur_fs_proxy As Microsoft.VisualBasic.MyServices.FileSystemProxy) As FileName
                wTempFileName = Me
                Me.FilePath = ur_fs_proxy.GetTempFileName
                Call ur_fs_proxy.DeleteFile(Me.FilePath)
            End Function 'wTempFileName
        End Class 'FileName
    End Class 'MxText-FileName

    Partial Public Class glbl
        Public Class gCboard
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Clear()
                Call My.Computer.Clipboard.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetText() As String
                GetText = My.Computer.Clipboard.GetText
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function SetText(ur_text As String) As Integer
                If HasText(ur_text) Then
                    Call My.Computer.Clipboard.SetText(ur_text)
                    SetText = 1 + ur_text.Length - ur_text.Replace(vbLf, mt).Length
                Else
                    Call My.Computer.Clipboard.Clear()
                    SetText = 0
                End If
            End Function 'SetText
        End Class 'gCboard

        Public Class gDiagnostics
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function IsRunningWindow(ur_title As String) As Boolean
                IsRunningWindow = False
                For Each objCUR_PROC In System.Diagnostics.Process.GetProcesses()
                    If objCUR_PROC.MainWindowHandle.ToInt32 <> 0 AndAlso
                      AreEqual(objCUR_PROC.MainWindowTitle, ur_title) Then
                        IsRunningWindow = True
                        Exit For
                    End If
                Next objCUR_PROC
            End Function 'IsRunningWindow

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Read_CommandLineText(ur_exec_path As String, ur_exec_param As String) As String
                Dim prcCOMMAND_LINE = gDiagnostics.Start_CommandLine_Program(ur_exec_path, ur_exec_param)
                Read_CommandLineText = prcCOMMAND_LINE.StandardOutput.ReadToEnd()
                prcCOMMAND_LINE.WaitForExit()
            End Function 'Read_CommandLineText

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Start_CommandLine_Program(ur_exec_path As String, ur_exec_param As String) As System.Diagnostics.Process
                Dim retPROCESS As New System.Diagnostics.Process()
                Start_CommandLine_Program = retPROCESS
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.UseShellExecute = False
                    prcINFO.RedirectStandardOutput = True
                    prcINFO.RedirectStandardError = True
                    prcINFO.CreateNoWindow = True
                End With 'prcINFO

                retPROCESS.Start()
            End Function 'Start_Procses

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Start_Windows_Program(ur_exec_path As String, ur_exec_param As String)
                Dim retPROCESS As New System.Diagnostics.Process()
                With 1 : Dim prcINFO = retPROCESS.StartInfo
                    prcINFO.Verb = "Open"
                    prcINFO.FileName = ur_exec_path
                    prcINFO.Arguments = ur_exec_param
                    prcINFO.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
                    prcINFO.UseShellExecute = True
                End With 'prcINFO

                retPROCESS.Start()
            End Sub 'Start_Procses
        End Class 'gDiagnostics

        Public Class gInteraction
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub AppActivate(ur_window_title As String)
                Microsoft.VisualBasic.Interaction.AppActivate(ur_window_title)
            End Sub
        End Class 'gInteraction

        Public Class gEnvironment
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function CommandLine() As String
                CommandLine = System.Environment.CommandLine
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ExpandEnvironmentVariables(ur_path As String) As String
                ExpandEnvironmentVariables = System.Environment.ExpandEnvironmentVariables(ur_path)
            End Function
        End Class 'gEnvironment

        Public Class gMsgBox
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetResult(ur_message As String, ur_style As MsgBoxStyle, ur_title As String) As MsgBoxResult
                GetResult = MsgBox(ur_message, ur_style, ur_title)
            End Function
        End Class 'gMsgBox

        Public Class gThread
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Sleep(ur_milliseconds As Integer)
                System.Threading.Thread.Sleep(ur_milliseconds)
            End Sub
        End Class 'gThread

        Public Class gWindowsFS
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Copy(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Copy(ur_source_path, ur_dest_path, True)
            End Sub
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub CreateDirectory(ur_folder_path As String)
                System.IO.Directory.CreateDirectory(ur_folder_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Delete(ur_path As String)
                System.IO.File.Delete(ur_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = System.IO.Directory.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetDirectories(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetDirectories = System.IO.Directory.GetDirectories(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function GetFullPath(ur_partial_path As String) As String
                GetFullPath = System.IO.Path.GetFullPath(ur_partial_path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasDir(ur_search_folder As String) As Boolean
                HasDir = System.IO.Directory.Exists(ur_search_folder)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function HasFile(ur_search_Path As String) As Boolean
                HasFile = System.IO.File.Exists(ur_search_Path)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Move(ur_source_path As String, ur_dest_path As String)
                System.IO.File.Move(ur_source_path, ur_dest_path)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadAllText(ur_file_path As String) As String
                ReadAllText = System.IO.File.ReadAllText(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function ReadStream(ur_file_path As String) As System.IO.StreamReader
                ReadStream = New System.IO.StreamReader(ur_file_path, Mx.gUTF8_FileEncoding())
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub WriteAllText(ur_file_path As String, ur_text As String)
                Call System.IO.File.WriteAllText(ur_file_path, ur_text, Mx.gUTF8_FileEncoding())
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function WriteStream(ur_file_path As String) As System.IO.StreamWriter
                WriteStream = New System.IO.StreamWriter(ur_file_path, False, Mx.gUTF8_FileEncoding())
            End Function
        End Class 'gWindowsFS
    End Class 'glbl

    Public Class TablePKEnum(Of E As {New, bitBASE}, P As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of P, T)
        Private PK As E

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(Optional ur_flag_populate_keys As Boolean = True)
            Me.ttb = New System.Collections.Generic.Dictionary(Of P, T)
            Me.PK = TRow(Of E).glbl.RefKeys.tr_b1(1)
            If ur_flag_populate_keys Then
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    Dim new_row = New T
                    new_row.v(Me.PK) = enmENTRY.name
                    Me.ttb.Add(enmENTRY, new_row)
                Next enmENTRY
            End If 'ur_empty_table
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ur_key As P) As Boolean
            ExistsKey = Me.ttb.ContainsKey(ur_key)
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim enmENTRY = prv.Get_PKStr(Me, ur_row)
            If enmENTRY Is Nothing Then
                Throw New System.Exception("Primary Key must exist in the enumeration: " & ur_row.v(Me.PK))

            ElseIf Me.ttb.ContainsKey(enmENTRY) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_row.v(Me.PK))

            Else
                Me.ttb.Add(enmENTRY, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            InsKey = ret
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKEnum(Of E, P, T)
            Dim ttbRET = New TablePKEnum(Of E, P, T)
            PersistRead = ttbRET
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Me.Ins(CType(row, T))
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T()
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ur_key As P) As T
            SelKey = Me.ttb.Item(ur_key)
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKEnum(Of E, P, T)
            Dim retTABLE = New TablePKEnum(Of E, P, T)(False)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ur_key As P) As T
            Dim ret As T = Nothing
            If Me.ttb.ContainsKey(ur_key) Then
                ret = Me.ttb.Item(ur_key)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(ur_key, ret)
            End If 'Me

            UseKey = ret
        End Function 'UseKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        Private Class prv
            Public Shared Sub Assign_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T, ur_key As P)
                ur_row.v(ur_table.PK) = ur_key.name
            End Sub 'Assign_PKStr

            Public Shared Function Get_PKStr(ur_table As TablePKEnum(Of E, P, T), ur_row As T) As P
                Dim ret As P = Nothing
                Dim strPK = ur_row.v(ur_table.PK)
                For Each enmENTRY In TRow(Of P).glbl.RefKeys
                    If AreEqual(enmENTRY.name, strPK) Then
                        ret = enmENTRY
                        Exit For
                    End If
                Next enmENTRY

                Get_PKStr = ret
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKEnum

    Public Class TablePKStr(Of E As {New, bitBASE}, T As {New, TRow(Of E)})
        Private ttb As System.Collections.Generic.Dictionary(Of String, T)
        Private PK As Objlist(Of E)

        <System.Diagnostics.DebuggerHidden()>
        Public Sub New(ur_pk_count As Integer)
            Me.ttb = New System.Collections.Generic.Dictionary(Of String, T)
            Me.PK = New Objlist(Of E)
            With 1 : Dim lstKEYS = TRow(Of E).glbl.RefKeys
                Dim intPK_COUNT = ur_pk_count
                If intPK_COUNT > lstKEYS.Count Then
                    intPK_COUNT = lstKEYS.Count
                End If

                For KEYCTR = 1 To ur_pk_count
                    Me.PK.Add(lstKEYS.Item(b0(KEYCTR)))
                Next
            End With 'lstKEYS
        End Sub 'New

        <System.Diagnostics.DebuggerHidden()>
        Public Function Count() As Integer
            Count = Me.ttb.Count
        End Function

        <System.Diagnostics.DebuggerHidden()>
        Public Function ExistsKey(ParamArray ur_key() As String) As Boolean
            ExistsKey = False
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("ExistsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                ExistsKey = Me.ttb.ContainsKey(strPK_KEY_COMBINED)
            End If 'ur_key
        End Function 'ExistsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function DelAll() As TablePKStr(Of E, T)
            DelAll = Me
            Call Me.ttb.Clear()
        End Function 'DelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function Ins(ur_row As T) As T
            Ins = ur_row
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_row)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

            Else
                Me.ttb.Add(strPK_KEY_COMBINED, ur_row)
            End If 'Me
        End Function 'Ins

        <System.Diagnostics.DebuggerHidden()>
        Public Function InsKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("InsKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & strPK_KEY_COMBINED)

                Else
                    ret = New T
                    Call prv.Assign_PKStr(Me, ret, ur_key)
                    Me.ttb.Add(strPK_KEY_COMBINED, ret)
                End If 'Me
            End If 'ur_key

            InsKey = ret
        End Function 'InsKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function PersistRead(ur_persist_path As String) As TablePKStr(Of E, T)
            PersistRead = Me
            For Each row In TRow(Of E).PersistRead(ur_persist_path)
                Dim new_row = New T
                For Each enmENTRY In new_row.RefColKeys
                    new_row.v(enmENTRY) = row.v(enmENTRY)
                Next

                Me.Ins(new_row)
            Next
        End Function 'PersistRead

        <System.Diagnostics.DebuggerHidden()>
        Public Sub PersistWrite(ur_persist_path As String)
            Dim ttbOUT = New Objlist(Of TRow(Of E))
            For Each entry In Me.ttb.Values
                ttbOUT.Add(entry)
            Next
            Call TRow(Of E).PersistWrite(ttbOUT, ur_persist_path)
        End Sub 'PersistWrite

        <System.Diagnostics.DebuggerHidden()>
        Public Function Sel(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            Sel = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'Sel

        Public ReadOnly Property SelAll() As Objlist(Of T)
            <System.Diagnostics.DebuggerHidden()>
            Get
                Dim lstRET = New Objlist(Of T)
                For Each kvpENTRY In Me.ttb
                    lstRET.Add(kvpENTRY.Value)
                Next

                SelAll = lstRET
            End Get
        End Property 'SelAll

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelDistinct(ur_col As E) As Sdata
            Dim ret = New Sdata
            SelDistinct = ret
            For Each kvpROW In Me.ttb

                Dim strVAL = kvpROW.Value.v(ur_col)
                Dim bolNEW_ENTRY = True
                For Each strENTRY In ret
                    If AreEqual(strENTRY, strVAL) Then
                        bolNEW_ENTRY = False
                    End If
                Next strENTRY

                If bolNEW_ENTRY Then
                    ret.Add(strVAL)
                End If
            Next kvpROW

            Call ret.Sort()
        End Function 'SelDistinct

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelFirst() As T
            If Me.ttb.Count = 0 Then
                SelFirst = New T
            Else
                SelFirst = Nothing
                For Each entry In Me.ttb.Keys
                    SelFirst = Me.ttb.Item(entry)
                    Exit For
                Next
            End If
        End Function 'SelFirst

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            If ur_key.Length <> Me.PK.Count Then
                Throw New System.Exception("SelKey requires all PK parameters: " & Me.PK.Count)

            Else
                Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
                If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                    ret = Me.ttb.Item(strPK_KEY_COMBINED)

                Else
                    ret = New T
                End If 'Me
            End If 'ur_key

            SelKey = ret
        End Function 'SelKey

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelNe(ur_col As E, ur_value As String) As TablePKStr(Of E, T)
            Dim retTABLE = New TablePKStr(Of E, T)(Me.PK.Count)
            SelNe = retTABLE
            For Each kvpROW In Me.ttb
                If AreEqual(kvpROW.Value.v(ur_col), ur_value) = False Then
                    retTABLE.Ins(kvpROW.Value)
                End If
            Next kvpROW
        End Function 'SelNe

        <System.Diagnostics.DebuggerHidden()>
        Public Function SelOnKey(ParamArray ur_key() As String) As TablePKStr(Of E, T)
            Dim ret = Me
            For KEYCTR = 1 To Me.PK.Count
                ret = ret.Sel(Me.PK.Item(b0(KEYCTR)), ur_key(b0(KEYCTR)))
            Next

            SelOnKey = ret
        End Function 'SelOnKey

        <System.Diagnostics.DebuggerHidden()>
        Public Overloads Function ToString(ur_hdr As Boolean) As String
            Dim stpRET = Strapd() : Dim intINDEX = 0 : For Each kvpREC In Me.ttb : intINDEX += 1
                stpRET.d(kvpREC.Value.ToString((intINDEX = 1) And ur_hdr))
            Next kvpREC : ToString = stpRET
        End Function 'ToString

        <System.Diagnostics.DebuggerHidden()>
        Public Function UseKey(ParamArray ur_key() As String) As T
            Dim ret As T = Nothing
            Dim strPK_KEY_COMBINED = prv.Get_PKStr(Me, ur_key)
            If Me.ttb.ContainsKey(strPK_KEY_COMBINED) Then
                ret = Me.ttb.Item(strPK_KEY_COMBINED)

            Else
                ret = New T
                Call prv.Assign_PKStr(Me, ret, ur_key)
                Me.ttb.Add(strPK_KEY_COMBINED, ret)
            End If

            UseKey = ret
        End Function 'UseKey

        Private Class prv
            <System.Diagnostics.DebuggerHidden()>
            Public Shared Sub Assign_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T, ur_key() As String)
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                For KEYCTR = 1 To intPK_KEYS
                    ur_row.v(ur_table.PK.Item(b0(KEYCTR))) = ur_key(b0(KEYCTR))
                Next
            End Sub 'Assign_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_key() As String) As String
                Dim intPK_KEYS = ur_key.Length
                If intPK_KEYS > ur_table.PK.Count Then
                    intPK_KEYS = ur_table.PK.Count
                End If

                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To intPK_KEYS
                    If KEYCTR = 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_key(b0(KEYCTR)).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr

            <System.Diagnostics.DebuggerHidden()>
            Public Shared Function Get_PKStr(ur_table As TablePKStr(Of E, T), ur_row As T) As String
                Dim stpPK_KEY_COMBINED = Strapd()
                For KEYCTR = 1 To ur_table.PK.Count
                    If KEYCTR > 1 Then stpPK_KEY_COMBINED.d(vbTab)
                    stpPK_KEY_COMBINED.d(ur_row.v_b1(KEYCTR).ToUpper)
                Next

                Get_PKStr = stpPK_KEY_COMBINED.ToString
            End Function 'Get_PKStr
        End Class 'prv
    End Class 'TablePKStr


    Partial Public Class Have
        Partial Private Class prv_sample
            Private Class Have
                Private Shared tblUserBowl As sUserBowl

                <System.Diagnostics.DebuggerHidden()>
                Private Shared Sub Connect()
                    If Have.tblUserBowl Is Nothing Then
                        Have.tblUserBowl = New sUserBowl
                    End If 'sdaTCOL_NAME
                End Sub 'Connect

                Public Class enmUB
                    Inherits bitBASE
                    Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                    Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
                End Class

                Public Class enmUN
                    Inherits bitBASE
                    Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p1 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared extra_p2 As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                    Public Shared to_clipboard As enmUN = TRow(Of enmUN).glbl.NewBitBase()
                End Class

                'Public Shared Function UserBowl() As sUserBowl
                '    Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
                '    Call Have.Connect()
                '    UserBowl = Have.tblUserBowl
                '    If bolFIRST_INIT Then
                '        Call Have.tblUserBowl.InsFrom_Application()
                '        Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                '        Call Have.tblUserBowl.Cboard_CmdlineAudit()
                '    End If
                'End Function 'UserBowl

                Public Class rUserBowl
                    Inherits TRow(Of enmUB)

                    <System.Diagnostics.DebuggerHidden()>
                    Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                        vt = Me
                        Me.v(ur_enm) = ur_val
                    End Function

                    'Public Shadows Function Link_Table(ur_child_table As Have.sReport_Detl, ParamArray ur_key_list() As bitRP) As sReport_Detl
                    '    Dim tblRET = New sReport_Detl
                    '    Link_Table = tblRET
                    '    Dim sdpXLAT = New SdPair(Of bitRT)
                    '    Dim stpKEY_BINDINGS = Strapd()
                    '    For Each keyRP In ur_key_list
                    '        stpKEY_BINDINGS.dS(keyRP.name)
                    '        For Each keyRT In ur_child_table.SelFirst.RefColKeys
                    '            If AreEqual(keyRT.name, keyRP.name) Then
                    '                sdpXLAT.d(keyRP.name, keyRT)
                    '            End If
                    '        Next keyRT
                    '    Next keyRP

                    '    If sdpXLAT.Count <> ur_key_list.Length Then
                    '        Throw New System.Exception("Key bindings not found for RT/RP join: " & stpKEY_BINDINGS.ToString)

                    '    Else
                    '        For Each trwJOIN In ur_child_table.SelAll
                    '            Dim bolFOUND = True
                    '            For Each keyRP In ur_key_list
                    '                Dim keyRT = sdpXLAT.l(keyRP.name)
                    '                If AreEqual(trwJOIN.v(keyRT), Me.v(keyRP)) = False Then
                    '                    bolFOUND = False
                    '                    Exit For
                    '                End If
                    '            Next keyRP

                    '            If bolFOUND Then
                    '                tblRET.Ins(trwJOIN)
                    '            End If
                    '        Next trwJOIN
                    '    End If 'sdpXLAT
                    'End Function 'Link_Table
                End Class 'rUserBowl

                Public Class sUserBowl
                    Inherits TablePKEnum(Of enmUB, enmUN, rUserBowl)

                    'Public Sub Cboard_CmdlineAudit()
                    '    If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    '        Dim strAUDIT = Me.ToString(True)
                    '        Dim ins_msg = Mx.Have.MessageBox.Ins(
                    '            New Mx.Have.rMessageBox().
                    '                vt(enmMB.title, Me.SelKey(enmUN.app_name).v(enmUB.contents)).
                    '                vt(enmMB.text, strAUDIT),
                    '            MsgBoxStyle.OkCancel
                    '            )
                    '        If ins_msg.vUserResponse = MsgBoxResult.Ok Then
                    '            Mx.Have.Clipboard.Ins(
                    '                New Mx.Have.rClipboard().
                    '                vt(enmCB.text, strAUDIT)
                    '                )
                    '        End If
                    '    End If
                    'End Sub 'Cboard_CmdlineAudit

                    'Public Function InsFrom_Application() As rUserBowl
                    '    Dim ret = New rUserBowl
                    '    InsFrom_Application = ret
                    '    'Me.InsKey(enmUN.app_name, New MxText.FileName().d(Mx.Class1.SourcePath).FileGroup)
                    '    'Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                    '    'Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                    '    Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                    '    Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                    '    Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                    '    For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    '        Me.Ins(
                    '            New Have.rUserBowl().
                    '            vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                    '            vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                    '            )
                    '    Next
                    'End Function 'InsFrom_Application

                    'Public Function ToCbrd(ur_hdr As Boolean) As Integer
                    '    ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
                    'End Function
                End Class 'sUserBowl
            End Class 'Have
        End Class 'prv_sample
    End Class 'Have.prv_sample
End Namespace 'Mx

VBNetProject\VBNetScript

VBCode WindowsOS
<<ext "VBNetScript.EXE">>

<<ext "VBNetScript.SLN">>

VBNS Project

DOC
<<glbl_article_list>>

VBNS Project\~MockTestReport

ErrorHandling Extract VBCode
```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
dbUserInputMock.vb
ScriptRun.vb
subs.vb
RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx2.Want.CompileCode_Report_errhnd(System.Environment.CommandLine)
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx2

Namespace Mx2
    Public Class Mock
        Public Class TextBox
            Public Text As String

            Public Sub New()
                Me.Text = Mx.mt
            End Sub
        End Class 'TextBox

        Public Class Form
            Public BackColor As System.Drawing.Color
            Public Text As String

            Public Sub New()
                Me.BackColor = Nothing
                Me.Text = Mx.mt
            End Sub

            Public Sub Close()
            End Sub
        End Class 'Form
    End Class 'Mock

    Public Class Want
        Public Shared Function CompileCode_Report_errhnd(ur_commandline_text As String) As Mx.Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Mx.Strapd()
            CompileCode_Report_errhnd = stpRET
            stpRET.d("RED").dLine()
            Dim objERR_LIST = New Mx.ErrListBase : Try
                Call Assistant.CompileCode_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'CompileCode_Report_errhnd
    End Class 'Want

    Public Class Assistant
        Public Shared Sub CompileCode_Report(ur_ret As Mx.Strap)
            Dim windowsfs_env = Have.WindowsFS
            Dim userbowl_cart = Have.UserBowl
            Dim appfolder_bowlname = enmUN.app_folder
            Dim mocktest_cart = Have.MockTest
            Dim intRECS_INSERTED = mocktest_cart.Apply(userbowl_cart, appfolder_bowlname, windowsfs_env)
            Dim intRECS_TESTED = mocktest_cart.Apply(windowsfs_env)

            Dim from_messagebox_bowlname = userbowl_cart.Apply(mocktest_cart, ur_ret)
        End Sub 'CompileCode_Report
    End Class 'Assistant

    Partial Public Class Have
        Partial Public Class sMockTest
            Public Function Apply(ur_userbowl_cart As Have.sUserBowl, ur_appfolder_bowlname As enmUN, ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_ADDED = 0
                Dim strSEARCH_TEST_NAME = "MockTest\*.mock_commandline.txt"
                Dim strSEARCH_RESULT_NAME = ".mock_expect.txt"
                Dim flnAPP_FOLDER = Mx.FileNamed.d(ur_userbowl_cart.SelKey(ur_appfolder_bowlname).Contents)
				Dim fltSEARCH_MOCK_COMMANDLINE = flnAPP_FOLDER.gCopy.d(strSEARCH_TEST_NAME)
                For Each strPATH In ur_windowsfs_env.GetFiles(fltSEARCH_MOCK_COMMANDLINE.gParentDir, fltSEARCH_MOCK_COMMANDLINE.Name, System.IO.SearchOption.TopDirectoryOnly)
					
                    Dim flnTEST_FILE_PATH = Mx.FileNamed.d(strPATH)
                    Dim rowMOCK_TEST = Me.InsKey(strPATH)
                    retREC_ADDED += 1
                    Dim flnTEST_CODE_PATH = flnTEST_FILE_PATH.gParentDir.d(Mx.FileNamed().d(flnTEST_FILE_PATH.FileGroup).FileGroup)
                    For Each strTEST_CODE_PATH In ur_windowsfs_env.GetFiles(flnTEST_CODE_PATH.gParentDir, flnTEST_CODE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.test_code_file, strTEST_CODE_PATH)
                        Exit For
                    Next
					
                    Dim flnRESULT_FILE_PATH = flnTEST_CODE_PATH.gCopy.dAppendEXT(strSEARCH_RESULT_NAME)
                    For Each strEXPECTED_RESULT_PATH In ur_windowsfs_env.GetFiles(flnRESULT_FILE_PATH.gParentDir, flnRESULT_FILE_PATH.Name, System.IO.SearchOption.TopDirectoryOnly)
                        rowMOCK_TEST.vt(enmMT.mock_expect_file, strEXPECTED_RESULT_PATH)
                        Exit For
                    Next
                Next strPATH

                Apply = retREC_ADDED
            End Function 'Apply ur_userbowl_cart

            Public Function Apply(ur_windowsfs_env As Have.glblWindowsFS) As Integer
                Dim retREC_TESTED = 0
                For Each rowMOCK_TEST In Me.SelAll
                    retREC_TESTED += 1
                    If Mx.HasText(rowMOCK_TEST.v(enmMT.test_code_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Test Code File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    ElseIf Mx.HasText(rowMOCK_TEST.v(enmMT.mock_expect_file)) = False Then
                        rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
						rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().d("Mock Expect File not found for").dS("").dSprtr("`", rowMOCK_TEST.v(enmMT.mock_commandline_file)).d("`"))

                    Else
						Dim strTEST_CODEFILE_PATH = rowMOCK_TEST.v(enmMT.test_code_file)
                        Dim strCOMMANDLINE_PARMS = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_commandline_file))
                        Dim strEXPECTED_RESULT = ur_windowsfs_env.ReadAllText(rowMOCK_TEST.v(enmMT.mock_expect_file))

                        Dim mockTextBox = New Mock.TextBox
                        Dim mockForm = New Mock.Form
                        Dim mockUserInput = New Mx.dbUserInput(mockForm, mockTextBox)
                        Dim stpTEST_COMMANDLINE = Mx.Strapd().d("vbnetscript.exe").dS("/path=").dSprtr(Mx.qs, strTEST_CODEFILE_PATH).d(Mx.qs).dS(strCOMMANDLINE_PARMS)
                        Call Mx.Want.Compile_And_Run_Script_errhnd(mockUserInput, stpTEST_COMMANDLINE)
                        Dim strFOUND_RESULT = mockTextBox.Text
                        If strFOUND_RESULT = strEXPECTED_RESULT Then
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "1")
						
                        Else
                            rowMOCK_TEST.vt(enmMT.test_pass_count, "0")
                            rowMOCK_TEST.vt(enmMT.test_result_text, Mx.Strapd().dSprtr("`", strCOMMANDLINE_PARMS).d("`").dS("expected").dS("").dSprtr("`", strEXPECTED_RESULT).d("`").d("; received").dSprtr("`", strFOUND_RESULT).d("`"))
                        End If 'strFOUND_RESULT
                    End If
                Next rowMOCK_TEST

                Apply = retREC_TESTED
            End Function 'Apply ur_windowsfs_env
        End Class 'sMockTest

        Partial Public Class sUserBowl
            Public Function Apply(ur_mocktest_cart As Have.sMockTest, ur_ret As Mx.Strap) As enmUN
                Dim retUN = enmUN.from_messagebox
                Apply = retUN

                Dim intTEST_PASS = 0
                Dim intTEST_FAIL = 0
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "1" Then
                        intTEST_PASS += 1

                    Else
                        intTEST_FAIL += 1
                    End If
                Next rowMOCK_TEST

                If intTEST_PASS = ur_mocktest_cart.SelAll.Count Then
                    ur_ret.Clear().dLine("GREEN").dLine()
                End If

                ur_ret.dLine(intTEST_PASS.ToString).dS("Tests passed")
                ur_ret.dLine(intTEST_FAIL.ToString).dS("Tests failed")
				ur_ret.dLine()
                For Each rowMOCK_TEST In ur_mocktest_cart.SelAll
                    If rowMOCK_TEST.v(enmMT.test_pass_count) = "0" Then
                        ur_ret.dLine(rowMOCK_TEST.v(enmMT.test_result_text))
						ur_ret.dLine()
                    End If
                Next rowMOCK_TEST
            End Function 'Apply ur_messagebox_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblMockTest As sMockTest
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblMockTest = New sMockTest
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmMT
        Inherits Mx.bitBASE
        Public Shared mock_commandline_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared mock_expect_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_code_file As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_result_text As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
        Public Shared test_pass_count As enmMT = Mx.TRow(Of enmMT).glbl.NewBitBase()
    End Class 'enmMT

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function MockTest() As sMockTest
            Call Have.Connect()
            MockTest = Have.tblMockTest
        End Function

        Public Class rMockTest
            Inherits Mx.TRow(Of enmMT)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmMT, ur_val As String) As rMockTest
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rMockTest

        Public Class sMockTest
            Inherits Mx.TablePKStr(Of enmMT, rMockTest)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                MyBase.New(1)
            End Sub
        End Class
    End Class 'enmMT

    Public Class enmUB
        Inherits Mx.bitBASE
        Public Shared bowl_name As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = Mx.TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits Mx.bitBASE
        Public Shared app_folder As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = Mx.TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits Mx.bitBASE
        Public Shared Ok As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = Mx.TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits Mx.TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = Mx.AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If Mx.HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = Mx.MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = Mx.qs & Have.CmdLineText.Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                Me.SelKey(enmUN.cmdline_table).Contents = Mx.qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(Mx.qs, Mx.qs & Mx.qs) & Mx.qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx2

VBNS Project\~VersionUpd

AssignVariable Filter VBCode
```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.FileUpdate_Report_errhnd
End Function
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.FileUpdate_Report_errhnd
'            If RetVal <> "QUIT" Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = "UrFolder"
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Public Shared Sub FileUpdate_Report(ur_ret As Strap)
            Dim userbowl_cart = Have.UserBowl
            Dim appname_bowlname = enmUN.app_name
            Dim appfolder_bowlname = enmUN.app_folder
            Dim windows_msgbox_env = Have.WindowsMsgBox
            Dim windows_fs_env = Have.WindowsFS
            Dim tempfile_cart = Have.TempFile
            tempfile_cart.Apply(userbowl_cart.SelKey(appfolder_bowlname), windows_fs_env)
            Dim report_output_bowlname = userbowl_cart.Apply(tempfile_cart)
            Dim from_messagebox_bowlname = userbowl_cart.Apply(
                ur_userbowl_text:=userbowl_cart.SelKey(report_output_bowlname),
                ur_userbowl_appname:=userbowl_cart.SelKey(appname_bowlname),
                ur_messagebox_env:=windows_msgbox_env
                )
        End Sub 'FileUpdate_Report

        Public Shared Function FileUpdate_Report_errhnd() As Strap
            Dim stpRET = Strapd()
            FileUpdate_Report_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call FileUpdate_Report(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'FileUpdate_Report_errhnd
    End Class 'Want

    Partial Public Class Have
        Partial Class sTempFile
            Public Sub Apply(ur_app_folder As Have.rUserBowl, ur_windows_fs_env As Have.glblWindowsFS)
                Dim flnROOT_FOLDER = FileNamed().d(ur_app_folder.v(enmUB.contents))
                Dim flnMY_PROJECT = flnROOT_FOLDER.gCopy.d("My Project")
                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnROOT_FOLDER, "*.vbproj", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.VBProj, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.VBProj).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.VBProj.name).dS("file in folder"))
                End If

                For Each strFILE_PATH In ur_windows_fs_env.GetFiles(flnMY_PROJECT, "AssemblyInfo.vb", System.IO.SearchOption.TopDirectoryOnly)
                    Me.InsKey(enmTN.AssemblyInfo, strFILE_PATH)
                    Exit For
                Next

                If HasText(Me.SelKey(enmTN.AssemblyInfo).v(enmTF.filename)) = False Then
                    Throw New System.Exception(Strapd().d("Could not find").dS(enmTN.AssemblyInfo.name).dS("file in folder"))
                End If
            End Sub 'Apply(ur_app_folder
        End Class 'sTempFile

        Partial Public Class sUserBowl
            Public Function Apply(ur_userbowl_text As Have.rUserBowl, ur_userbowl_appname As Have.rUserBowl, ur_messagebox_env As Have.glblWindowsMsgBox) As bitBASE
                Dim retUN = enmUN.from_messagebox
                Apply = retUN
                Dim enrUSER_INPUT = ur_messagebox_env.GetResult(
                    ur_message:=ur_userbowl_text.v(enmUB.contents),
                    ur_title:=ur_userbowl_appname.v(enmUB.contents),
                    ur_style:=MsgBoxStyle.OkOnly
                    )

                If enrUSER_INPUT = MsgBoxResult.Ok Then
                    Me.InsKey(retUN, enmUR.Ok)
                End If
            End Function 'Apply ur_messagebox_cart

            Public Function Apply(ur_tempfile_cart As Have.sTempFile) As enmUN
                Dim retUN = enmUN.report_output
                Apply = retUN
                Dim strDATE = Today.ToString("yyyy.MM.dd")
                Dim intCURRENT = 1

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.VBProj.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<ApplicationRevision>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationRevision>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, InStr(strPARSE, "<") - 1)
                                    If System.Int32.TryParse(strPARSE, intCURRENT) Then
                                        intCURRENT += 1
                                    End If

                                ElseIf StartingWithText(strLINE.TrimStart, "<ApplicationVersion>") Then
                                    Dim strPARSE = Mid(strLINE.TrimStart, "<ApplicationVersion>".Length + 1)
                                    strPARSE = Mid(strPARSE, 1, 10)
                                    If AreEqual(strPARSE, strDATE) = False Then
                                        intCURRENT = 1
                                    End If 'strPARSE

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationRevision>")
                                    stmSECOND.Write(intCURRENT)
                                    stmSECOND.WriteLine("</ApplicationRevision>")

                                    stmSECOND.Write(Mid(strLINE, 1, InStr(strLINE, "<") - 1))
                                    stmSECOND.Write("<ApplicationVersion>")
                                    stmSECOND.Write(Strapd().d(strDATE).d(intCURRENT.ToString("00")).d(".%2a"))
                                    stmSECOND.WriteLine("</ApplicationVersion>")

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                For Each trwFILE In ur_tempfile_cart.Sel(enmTF.file_search, enmTN.AssemblyInfo.name).SelAll
                    Dim flnSOURCE = FileNamed().d(trwFILE.v(enmTF.filename))
                    Dim flnTEMP = flnSOURCE.gCopy.dAppendEXT("tmp")
                    Using stmSECOND = New System.IO.StreamWriter(flnTEMP, False, gUTF8_FileEncoding)
                        Using stmORIG = New System.IO.StreamReader(flnSOURCE, gUTF8_FileEncoding)
                            While Not stmORIG.EndOfStream
                                Dim strLINE = stmORIG.ReadLine
                                If StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyVersion(") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyVersion").d("(").d(qs).d(Today.ToString("yyyy.MM.dd")).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                ElseIf StartingWithText(strLINE.TrimStart, "<Assembly: AssemblyFileVersion") Then
                                    stmSECOND.WriteLine(Strapd().d("<").d("Assembly: AssemblyFileVersion").d("(").d(qs).d(strDATE).d(intCURRENT.ToString("00")).d(".00").d(qs).d(")").d(">"))

                                Else 'strLINE
                                    stmSECOND.WriteLine(strLINE)
                                End If 'strLINE
                            End While 'stmORIG
                        End Using 'stmORIG
                    End Using 'stmSECOND

                    Call glbl.gWindowsFS.Delete(flnSOURCE)
                    Call glbl.gWindowsFS.Move(flnTEMP, flnSOURCE)
                Next trwFILE

                Me.InsKey(retUN, Strapd().d("Files updated:").dS(ur_tempfile_cart.SelAll.Count.ToString))
            End Function 'Apply ur_tempfield_cart
        End Class 'sUserBowl
    End Class 'Have


    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblTempFile As sTempFile
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblTempFile = New sTempFile
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmTF
        Inherits bitBASE
        Public Shared file_search As enmTF = TRow(Of enmTF).glbl.NewBitBase()
        Public Shared filename As enmTF = TRow(Of enmTF).glbl.NewBitBase()
    End Class

    Public Class enmTN
        Inherits bitBASE
        Public Shared AssemblyInfo As enmTN = TRow(Of enmTN).glbl.NewBitBase()
        Public Shared VBProj As enmTN = TRow(Of enmTN).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function TempFile() As sTempFile
            Call Have.Connect()
            TempFile = Have.tblTempFile
        End Function

        Public Class rTempFile
            Inherits TRow(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmTF, ur_val As String) As rTempFile
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rTempFile

        Public Class sTempFile
            Private ttb As Objlist(Of rTempFile)
            Private PK As Objlist(Of enmTF)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rTempFile)
                Me.PK = New Objlist(Of enmTF)
                Me.PK.Add(enmTF.file_search)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Del(ur_col As enmTF, ur_val As String)
                For ROWCTR = Me.ttb.Count To 1 Step -1
                    If AreEqual(Me.ttb.tr_b1(ROWCTR).v(ur_col), ur_val) Then
                        Me.ttb.RemoveAt(b0(ROWCTR))
                    End If
                Next ROWCTR
            End Sub 'Del

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Ins(ur_from As rTempFile)
                Dim ttbSEL = Me
                Dim stpPK_LIST = Strapd()
                For Each keyPK In Me.PK
                    Dim strCUR_KEY = ur_from.v(keyPK)
                    If stpPK_LIST.Length > 0 Then stpPK_LIST.d(", ")
                    stpPK_LIST.d(strCUR_KEY)
                    If HasText(strCUR_KEY) = False Then
                        Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("PK value must have data:").dS(keyPK.name))
                    Else
                        ttbSEL = ttbSEL.Sel(keyPK, ur_from.v(keyPK))
                    End If
                Next keyPK

                If ttbSEL.SelAll.Count > 0 Then
                    Throw New System.Exception(Strapd().d(Me.GetType.Name).dS("must have unique PK values:").dS(stpPK_LIST.ToString))
                Else
                    Me.ttb.Add(ur_from)
                End If
            End Sub 'Ins

            <System.Diagnostics.DebuggerHidden()>
            Public Sub InsKey(ur_key As enmTN, ur_val As String)
                Dim ret = Me.SelKey(ur_key)
                If HasText(ret.v(enmTF.filename)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmTF.filename, ur_val)
                End If
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmTF, ur_value As String) As sTempFile
                Dim retUB = New sTempFile
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rTempFile)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmTN) As rTempFile
                Dim ret As rTempFile = Nothing
                Dim strKEY = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmTF.file_search), strKEY) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rTempFile
                    Me.ttb.Add(
                        ret.
                        vt(enmTF.file_search, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sTempFile
    End Class 'TF

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmd_export_cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.tblUserBowl Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rUserBowl

        Public Class sUserBowl
            Private ttb As Objlist(Of rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rUserBowl)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmd_export_cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim ins_msg = Have.WindowsMsgBox.GetResult(
                        ur_message:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_title:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If ins_msg = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(
                            strAUDIT
                            )
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rUserBowl) As rUserBowl
                Ins = ur_from
                Me.ttb.Add(ur_from)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As String) As rUserBowl
                Dim ret = Me.SelKey(ur_key)
                InsKey = ret
                If HasText(ret.v(enmUB.contents)) Then
                    Throw New System.Exception("Cannot insert duplicate key for key: " & ur_key.name)
                Else
                    ret.vt(enmUB.contents, ur_val)
                End If
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsKey(ur_key As enmUN, ur_val As enmUR) As rUserBowl
                InsKey = Me.InsKey(ur_key, ur_val.name)
            End Function 'InsKey

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.InsKey(enmUN.app_name, FileNamed().d(Mx.Class1.SourcePath).FileGroup)
                Me.InsKey(enmUN.app_path, Mx.Class1.SourcePath)
                Me.InsKey(enmUN.app_folder, Mx.Class1.SourceFolder)

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, System.Environment.CommandLine)
                Me.InsKey(enmUN.cmdline_orig, qs & System.Environment.CommandLine.Replace(qs, qs & qs) & qs)
                Me.InsKey(enmUN.cmdline_table, qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs)
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Ins(
                        New Have.rUserBowl().
                        vt(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).
                        vt(enmUB.contents, rowFOUND.v(enmUB.contents))
                        )
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function Sel(ur_col As enmUB, ur_value As String) As sUserBowl
                Dim retUB = New sUserBowl
                Sel = retUB
                For Each rowUB In Me.ttb
                    If AreEqual(rowUB.v(ur_col), ur_value) Then
                        retUB.Ins(rowUB)
                    End If
                Next
            End Function 'Sel

            Public ReadOnly Property SelAll() As Objlist(Of rUserBowl)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Function SelKey(ur_key As enmUN) As rUserBowl
                Dim ret As rUserBowl = Nothing
                Dim strUN = ur_key.name
                For Each row In Me.ttb
                    If AreEqual(row.v(enmUB.bowl_name), strUN) Then
                        ret = row
                        Exit For
                    End If
                Next row

                If ret Is Nothing Then
                    ret = New rUserBowl
                    Me.ttb.Add(
                        ret.
                        vt(enmUB.bowl_name, ur_key.name)
                        )
                End If

                SelKey = ret
            End Function 'SelKey

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

VBNS Project\Roman to Decimal

Numbers Extract VBCode
<<ext "Roman to Decimal ZIP">>

* Asks for a Roman Numeral
* Returns a decimal number or an error with the invalid sequence and the broken rule

```
Namespace Mx
	Public Class mb
		Public Shared FirstExec As Object
		Public Shared uinput As Microsoft.VisualBasic.MsgBoxResult

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub ask(ur_text As String)
			Call prv.Connect()
			If mb.uinput <> MsgBoxResult.Cancel Then
				mb.uinput = Microsoft.VisualBasic.MsgBox(ur_text, MsgBoxStyle.OkCancel, "")
			End If
		End Sub 'ask

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Function GetText(ur_question As String) As String
			GetText = Microsoft.VisualBasic.InputBox(ur_question, "")
		End Function

		<System.Diagnostics.DebuggerHidden()>
		Public Shared Sub reset()
			Call prv.Connect()
			mb.uinput = MsgBoxResult.Ok
		End Sub

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Sub Connect()
				If mb.FirstExec Is Nothing Then
					mb.uinput = MsgBoxResult.Ok
					mb.FirstExec = "done"
				End If
			End Sub 'Connect
		End Class 'prv
	End Class 'mb

	Public Class UserAction
		Public Shared Function Roman_Numeral_Conversion_Report() As String
			mb.reset()
			Dim strRET_MSG = ""
			Dim strNUMERAL = mb.GetText("Enter a Roman numeral")
			Dim strDECIMAL = Assistant.Roman_Numeral_Conversion_Result(strNUMERAL)
			strRET_MSG = strNUMERAL & " rom. = " & strDECIMAL & " dec."
			Roman_Numeral_Conversion_Report = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Report
	End Class 'UserAction

	Public Class Assistant
		Public Shared Function Roman_Numeral_Conversion_Result(ur_numeral As String) As String
			Dim strRET_MSG = ""
			Dim rmnNUMERAL = New Mx.glblRomanNumeral(ur_numeral)
			strRET_MSG = rmnNUMERAL.Validation_Message
			If strRET_MSG = "" Then
				strRET_MSG = rmnNUMERAL.ToInteger.ToString
			End If

			Roman_Numeral_Conversion_Result = strRET_MSG
		End Function 'Roman_Numeral_Conversion_Result
	End Class 'Assistant

	Public Class glblRomanNumeral
		Private strpNumeral As String

		Private Enum enmLH
			low_or_high_number
			high_number
			low_number
		End Enum

		Private siaSymbol_Size As Mx.sia

		<System.Diagnostics.DebuggerHidden()>
		Public Sub New(ur_numeral As String)
			Me.strpNumeral = ur_numeral.Trim.ToUpper
			Me.siaSymbol_Size = prv.glbl_Symbol_Sizes()
		End Sub

		Public ReadOnly Property Numeral As String
			<System.Diagnostics.DebuggerHidden()>
			Get
				Numeral = Me.strpNumeral
			End Get
		End Property 'Numeral

		Public Function IsValid() As Boolean
			IsValid = (Me.Validation_Message = "")
		End Function

		Public Function Validation_Message() As String
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_Valid

			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_Valid(clrRET_STATE, "", symbol_size_table)

			Validation_Message = clrRET_STATE.strNOTICE_MSG
		End Function 'Validation_Message

		Public Function ToInteger() As Integer
			Dim symbol_size_table = Me.siaSymbol_Size
			Dim strBASE = Me.strpNumeral
			Dim clrRET_STATE = New prv.Loop_State
			For CHRCTR = 1 To strBASE.Length
				Dim strCUR_CHAR = Mid(strBASE, CHRCTR, 1)
				Dim clPREV_STATE = clrRET_STATE
				clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, strCUR_CHAR, symbol_size_table)
			Next CHRCTR

			clrRET_STATE = prv.Loop_Return_State(clrRET_STATE, "", symbol_size_table)

			ToInteger = clrRET_STATE.intRET_NUM
		End Function 'ToInteger

		Private Class prv
			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function glbl_Symbol_Sizes() As Mx.sia
				Dim retSIA = New Mx.sia
				glbl_Symbol_Sizes = retSIA
				retSIA.Add("I", 1)
				retSIA.Add("V", 5)
				retSIA.Add("X", 10)
				retSIA.Add("L", 50)
				retSIA.Add("C", 100)
				retSIA.Add("D", 500)
				retSIA.Add("M", 1000)

				glbl_Symbol_Sizes = retSIA
			End Function 'glbl_Symbol_Sizes

			Public Class Loop_State
				Public enrSTATE As enmLH
				Public strLOW_OR_HIGH_TEMP As String
				Public intRET_NUM As Integer

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Me.enrSTATE = enmLH.high_number
					Me.strLOW_OR_HIGH_TEMP = ""
					Me.intRET_NUM = 0
				End Sub 'New
			End Class 'Loop_State

			Public Class Loop_Valid
				Public strVAL_FOUR As String
				Public strVAL_THREE As String
				Public strVAL_TWO As String
				Public strVAL_ONE As String
				Public intVAL_FOUR As Integer
				Public intVAL_THREE As Integer
				Public intVAL_TWO As Integer
				Public intVAL_ONE As Integer
				Public strNOTICE_MSG As String

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New()
					Call prvLoop_Valid.Reset_Symobls(Me)
					Me.strNOTICE_MSG = ""
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub New(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia)
					Me.strVAL_FOUR = ur_state.strVAL_THREE
					Me.intVAL_FOUR = ur_state.intVAL_THREE
					Me.strVAL_THREE = ur_state.strVAL_TWO
					Me.intVAL_THREE = ur_state.intVAL_TWO
					Me.strVAL_TWO = ur_state.strVAL_ONE
					Me.intVAL_TWO = ur_state.intVAL_ONE
					Me.strVAL_ONE = ur_new_symbol
					Me.intVAL_ONE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
					Me.strNOTICE_MSG = ur_state.strNOTICE_MSG
				End Sub 'New

				<System.Diagnostics.DebuggerHidden()>
				Public Sub Assign_NoticeMsg(ur_message As String)
					If strNOTICE_MSG <> "" Then
						strNOTICE_MSG &= vbCrLf & vbCrLf
					End If

					strNOTICE_MSG &= ur_message
					Call prvLoop_Valid.Reset_Symobls(Me)
				End Sub 'Assign_NoticeMsg

				Private Class prvLoop_Valid
					Public Shared Sub Reset_Symobls(ur_state As prv.Loop_Valid)
						ur_state.strVAL_FOUR = ""
						ur_state.intVAL_FOUR = 0
						ur_state.strVAL_THREE = ""
						ur_state.intVAL_THREE = 0
						ur_state.strVAL_TWO = ""
						ur_state.intVAL_TWO = 0
						ur_state.strVAL_ONE = ""
						ur_state.intVAL_ONE = 0
					End Sub 'Reset_Symobls
				End Class 'prv
			End Class 'Loop_Valid

			Public Shared Function Loop_Return_Valid(ur_state As prv.Loop_Valid, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_Valid
				Dim retSTATE = New prv.Loop_Valid(ur_state, ur_new_symbol, ur_symbol_size)
				Loop_Return_Valid = retSTATE
				If retSTATE.strVAL_ONE <> "" Then
					If retSTATE.intVAL_ONE = 0 Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							If strLIST <> "" Then
								strLIST &= ", "
							End If

							strLIST &= strENTRY
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used in Roman numerals.")

					ElseIf retSTATE.strVAL_FOUR = retSTATE.strVAL_THREE AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_TWO AndAlso
					  retSTATE.strVAL_FOUR = retSTATE.strVAL_ONE Then
						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_FOUR & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & ur_new_symbol & "] is not valid: A single symbol may not be repeated more than three times.")

					ElseIf retSTATE.strVAL_TWO = retSTATE.strVAL_ONE AndAlso
					  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
						Dim strLIST = ""
						For Each strENTRY In ur_symbol_size.Keys
							Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
							If Left(strENTRY_VAL, 1) = "1" Then
								If strLIST <> "" Then
									strLIST &= ", "
								End If

								strLIST &= strENTRY
							End If
						Next strENTRY

						retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be repeated.")

					ElseIf retSTATE.strVAL_TWO <> "" Then
						If retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  Left(retSTATE.intVAL_ONE.ToString, 1) <> "1" Then
							Dim strLIST = ""
							For Each strENTRY In ur_symbol_size.Keys
								Dim strENTRY_VAL = prv.Numeral_To_Int(ur_symbol_size, strENTRY).ToString
								If Left(strENTRY_VAL, 1) = "1" Then
									If strLIST <> "" Then
										strLIST &= ", "
									End If

									strLIST &= strENTRY
								End If
							Next strENTRY

							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: Only the symbols [" & strLIST & "] may be used as the lower symbol followed by a higher symbol.")

						ElseIf retSTATE.intVAL_ONE > retSTATE.intVAL_TWO AndAlso
						  retSTATE.intVAL_ONE <> retSTATE.intVAL_TWO * 10 Then
							retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: The lower symbol must be ten times less value than the following higher symbol.")

						ElseIf retSTATE.strVAL_THREE <> "" Then
							If retSTATE.intVAL_TWO > retSTATE.intVAL_ONE AndAlso
							  retSTATE.intVAL_ONE >= retSTATE.intVAL_THREE Then
								retSTATE.Assign_NoticeMsg("[" & retSTATE.strVAL_THREE & retSTATE.strVAL_TWO & retSTATE.strVAL_ONE & "] is not valid: A lower symbol followed by higher symbol must be followed by lower symbol than the first of the series.")
							End If
						End If 'strVAL_THREE
					End If 'strVAL_TWO
				End If 'strVAL_ONE
			End Function 'Loop_Return_Valid

			Public Shared Function Loop_Return_State(ur_state As prv.Loop_State, ur_new_symbol As String, ur_symbol_size As Mx.sia) As prv.Loop_State
				Dim retSTATE = New prv.Loop_State
				Loop_Return_State = retSTATE

				Dim intNEW_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_new_symbol)
				Dim intLOW_OR_HIGH_VALUE = prv.Numeral_To_Int(ur_symbol_size, ur_state.strLOW_OR_HIGH_TEMP)
				If ur_state.strLOW_OR_HIGH_TEMP = "" Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM
					retSTATE.enrSTATE = enmLH.low_or_high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol

				ElseIf intNEW_VALUE > intLOW_OR_HIGH_VALUE Then
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intNEW_VALUE - intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.high_number
					retSTATE.strLOW_OR_HIGH_TEMP = ""

				Else
					retSTATE.intRET_NUM = ur_state.intRET_NUM + intLOW_OR_HIGH_VALUE
					retSTATE.enrSTATE = enmLH.low_number
					retSTATE.strLOW_OR_HIGH_TEMP = ur_new_symbol
				End If
			End Function 'Loop_Return_State

			<System.Diagnostics.DebuggerHidden()>
			Public Shared Function Numeral_To_Int(ur_symbol_size As Mx.sia, ur_numeral As String) As Integer
				Numeral_To_Int = 0
				If ur_symbol_size.ContainsKey(ur_numeral) Then
					Numeral_To_Int = ur_symbol_size.Item(ur_numeral)
				End If
			End Function 'Numeral_To_Int
		End Class 'prv
	End Class 'glblRomanNumeral

	Public Class sia
		Inherits System.Collections.Generic.Dictionary(Of String, Integer)
	End Class
End Namespace 'Mx

VBNS Project\Wiki_Move_HTM

TWCard Filter VBCode
<<ext "Wiki Move HTM">>

```
@echo off
@SET mx_dir=%CD%
@SET countloops=20
:mx_search
@set /a countloops-=1
@FOR %%i IN ("%mx_dir%") DO IF EXIST %%~si\MxClasses\VBNetScript.exe GOTO mx_found
@FOR %%i IN ("%mx_dir%\..") DO SET mx_dir=%%~si
@IF %countloops%==0 GOTO mx_max_loops
@GOTO mx_search

:mx_max_loops
@ECHO Cannot find MxClasses\VBNetScript.exe within 20 parent directories
@PAUSE
@GOTO mx_end

:mx_found
@START "" "%mx_dir%\MxClasses\VBNetScript.exe" /path=%0

:mx_end
@EXIT
MxClasses\DLL_WinForm2019m09d13\System.Drawing.dll
MxClasses\DLL_WinForm2019m09d13\System.Windows.Forms.dll
MxClasses\MxBaseEc13.vb
RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
End Function '2021m01d03
End Class
End Namespace

'Namespace Mx
'    Module subs
'        Sub Main()
'            Dim RetVal = Mx.Want.UITimer_to_Poll_FileDir_And_Move_errhnd(System.Environment.CommandLine)
'            If Mx.AreEqual(RetVal, "QUIT") = False Then MsgBox(RetVal)
'        End Sub
'    End Module 'subs

'    Public Class Class1
'        Public Shared SourceFolder As String = My.Application.Info.DirectoryPath.Replace("\bin\Debug", "")
'        Public Shared SourcePath As String = "UrFolder\MyApp.exe"
'    End Class
'End Namespace 'Mx

Namespace Mx
    Public Class Want
        Const strLIT_WIKI_MOVE_5_SEC = "Wiki Move 5-Sec"
        Const strvLIT_USER_PROFILE_DOWNLOADS = "%USERPROFILE%\downloads"
        Const strLIT_STAR_DOT_HTM = "WikiMove_*-stamp-*.htm"
        Const strLIT_STAR_DOT_HTML = "WikiMove_*-stamp-*.html"
        Const strLIT_STAR_DOT_CARDTXT = "WikiMove_*-stamp-*.card*.txt"

        Public Shared Sub UITimer_to_Poll_FileDir_And_Move(ur_ret As Strap)
            ur_ret.d("QUIT")
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            Dim strUI_FORM_TITLE = strLIT_WIKI_MOVE_5_SEC
            userbowl_cart.SelKey(uiform_title_bowlname).Contents = strUI_FORM_TITLE
            userbowl_cart.SelKey(enmUN.poll_folder).Contents = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)
            If glbl.gDiagnostics.IsRunningWindow(strUI_FORM_TITLE) Then
                glbl.gInteraction.AppActivate(strUI_FORM_TITLE)

            Else
                Dim objFORM = New Mx.WikiMove_Form()
                objFORM.Text = userbowl_cart.SelKey(enmUN.uiform_title).v(enmUB.contents)
                Call objFORM.Display_FolderList()
                objFORM.tmrFIVE_SEC.Start()
                Dim strNEW_DATA_FOLDER = glbl.gEnvironment.ExpandEnvironmentVariables(strvLIT_USER_PROFILE_DOWNLOADS)

                'System.Windows.Forms.Application.Run(objFORM) only works from a command line program with no forms open. VBNetScript already has a form open.
                Call objFORM.ShowDialog()
            End If 'gDiagnostics
        End Sub 'UITimer_to_Poll_FileDir_And_Move

        Public Shared Function UITimer_to_Poll_FileDir_And_Move_errhnd(ur_commandline_text As String) As Strap
            Have.CmdLineText = ur_commandline_text
            Dim stpRET = Strapd()
            UITimer_to_Poll_FileDir_And_Move_errhnd = stpRET
            stpRET.d("QUIT")
            Dim objERR_LIST = New ErrListBase : Try
                Call UITimer_to_Poll_FileDir_And_Move(stpRET)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                stpRET.Clear().d(objERR_LIST.ToString)
            End If
        End Function 'UITimer_to_Poll_FileDir_And_Move_errhnd

        Public Shared Sub Poll_FileDir_And_Move(ur_ui_form As WikiMove_Form)
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            Dim windows_fs_cart = Have.WindowsFS
            Dim filemove_cart = Have.FileMove
            Call ur_ui_form.Display_FolderList()
            filemove_cart.DelAll()
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTM)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_HTML)
            filemove_cart.Apply(windows_fs_cart, userbowl_cart, pollfolder_bowlname, strLIT_STAR_DOT_CARDTXT)
            filemove_cart.Move_Files()
            Dim report_output_bowlname = userbowl_cart.Apply(filemove_cart)
            Dim strREPORT_OUTPUT = userbowl_cart.SelKey(report_output_bowlname).v(enmUB.contents)
            If HasText(strREPORT_OUTPUT) Then
                ur_ui_form.txtOUTPUT.Text = strREPORT_OUTPUT & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move

        Public Shared Sub Poll_FileDir_And_Move_errhnd(ur_ui_form As WikiMove_Form)
            Dim objERR_LIST = New ErrListBase : Try
                Call Poll_FileDir_And_Move(ur_ui_form:=ur_ui_form)

            Catch ex As System.Exception
                Call objERR_LIST.dError_Stack(ex)
            End Try

            If objERR_LIST.Found Then
                ur_ui_form.txtOUTPUT.Text = objERR_LIST.ToString & vbCrLf & ur_ui_form.txtOUTPUT.Text
                ur_ui_form.intSHOW_FORM = 1
            End If
        End Sub 'Poll_FileDir_And_Move_errhnd

        Public Class CombineTextOutput
            Public gText As Strap
            Public gFolderList As Sdata

            Public Sub New(ur_text As Strap, ur_folder_list As Sdata)
                Me.gText = ur_text
                Me.gFolderList = ur_folder_list
            End Sub
        End Class 'CombineTextOutput
    End Class 'sub_main

    Public Class WikiMove_Form
        Inherits System.Windows.Forms.Form

        Public tmrFIVE_SEC As System.Windows.Forms.Timer
        Public txtOUTPUT As System.Windows.Forms.TextBox
        Public intSHOW_FORM As Integer

        Public Sub New()
            Me.intSHOW_FORM = 1

            Me.Name = "Wiki_Move"
            Me.Size = New System.Drawing.Size(400, 400)
            Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen

            Me.txtOUTPUT = New System.Windows.Forms.TextBox()
            Me.txtOUTPUT.Name = "txtOUTPUT"
            Me.txtOUTPUT.Multiline = True
            Me.txtOUTPUT.ScrollBars = System.Windows.Forms.ScrollBars.Vertical
            Me.txtOUTPUT.Dock = System.Windows.Forms.DockStyle.Fill
            Me.Controls.Add(Me.txtOUTPUT)

            Me.tmrFIVE_SEC = New System.Windows.Forms.Timer()
            Me.tmrFIVE_SEC.Interval = 50
            AddHandler Me.tmrFIVE_SEC.Tick, AddressOf Timer1_Tick
        End Sub 'New

        Sub Display_FolderList()
            Dim userbowl_cart = Have.UserBowl
            Dim pollfolder_bowlname = enmUN.poll_folder
            If HasText(Me.txtOUTPUT.Text) = False Then
                Me.txtOUTPUT.Text = Strapd().dLine("Listening:").dS(userbowl_cart.SelKey(pollfolder_bowlname).v(enmUB.contents)).dLine().d(Me.txtOUTPUT.Text)
            End If
        End Sub 'Display_FolderList

        Sub Look_For_Files()
            Call Mx.Want.Poll_FileDir_And_Move_errhnd(Me)
        End Sub

        Sub Show_Saved()
            Dim userbowl_cart = Have.UserBowl
            Dim uiform_title_bowlname = enmUN.uiform_title
            If Me.intSHOW_FORM = 1 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Normal
                Call AppActivate(userbowl_cart.SelKey(uiform_title_bowlname).v(enmUB.contents))
                Me.tmrFIVE_SEC.Interval = 800
                Me.intSHOW_FORM = 2

            ElseIf Me.intSHOW_FORM = 2 Then
                Me.WindowState = System.Windows.Forms.FormWindowState.Minimized
                Me.intSHOW_FORM = 0

            ElseIf Me.intSHOW_FORM = 0 Then
                If Me.WindowState <> System.Windows.Forms.FormWindowState.Minimized Then
                    Me.intSHOW_FORM = 6
                End If

            Else
                Me.intSHOW_FORM -= 1
            End If
        End Sub 'Show_Saved

        Sub Timer1_Tick(sender As Object, e As System.EventArgs)
            Me.tmrFIVE_SEC.Stop()
            Me.tmrFIVE_SEC.Interval = 5000
            Call Look_For_Files()
            Call Show_Saved()
            Me.tmrFIVE_SEC.Start()
        End Sub 'Timer1_Tick
    End Class 'WikiMove_Form




    Public Class Have
        Partial Class sFileMove
            Public Sub Apply(ur_windows_fs_cart As Have.glblWindowsFS, ur_userbowl_cart As Have.sUserBowl, ur_poll_folder_bowlname As enmUN, ur_filespec As String)
                Dim strPOLL_FOLDER = ur_userbowl_cart.SelKey(ur_poll_folder_bowlname).Contents
                For Each strFILE_PATH In ur_windows_fs_cart.GetFiles(strPOLL_FOLDER, ur_filespec, System.IO.SearchOption.TopDirectoryOnly)
                    Dim flnFILE_NAME = FileNamed().d(strFILE_PATH)
                    Dim sdaEXT_LIST = flnFILE_NAME.ExtList
                    Dim strDEST_PATH_ENCODED_IN_NAME = flnFILE_NAME.Name.Substring("WikiMove_".Length)
                    Dim strDEST_PATH = strDEST_PATH_ENCODED_IN_NAME.Replace("-colon-", ":").Replace("-fslash-", "\")
                    Dim intSTAMP = InStr(strDEST_PATH, "-stamp-")
                    strDEST_PATH = Left(strDEST_PATH, intSTAMP - 1)
                    Dim strEXT = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count))
                    If sdaEXT_LIST.Count > 1 Then
                        Dim strEXT2 = sdaEXT_LIST.Item(b0(sdaEXT_LIST.Count - 1))
                        If AreEqual(strEXT, ".txt") AndAlso
                          StartingWithText(strEXT2, ".card") Then
                            strEXT = ".card.txt"
                        End If
                    End If 'sdaEXT_LIST

                    strDEST_PATH &= strEXT
                    Me.Ins(
                        New rFileMove().
                        vt(enmFM.src_file_path, strFILE_PATH).
                        vt(enmFM.dest_file_path, strDEST_PATH)
                        )
                Next strFILE_PATH
            End Sub 'Apply ur_windows_fs_cart

            Public Sub Move_Files()
                Dim lstLEN = New System.Collections.Generic.List(Of Integer)
                For Each rowFILE In Me.SelAll
                    Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                    Dim intLEN = strFILE_PATH.Length
                    If lstLEN.Contains(intLEN) = False Then
                        lstLEN.Add(intLEN)
                    End If
                Next rowFILE

                Call lstLEN.Sort()
                For Each intLEN In lstLEN
                    For Each rowFILE In Me.SelAll
                        Dim strFILE_PATH = rowFILE.v(enmFM.src_file_path)
                        If strFILE_PATH.Length = intLEN Then
                            Dim strDEST_PATH = rowFILE.v(enmFM.dest_file_path)
                            glbl.gWindowsFS.Move(strFILE_PATH, strFILE_PATH & ".TDLY")
                            glbl.gWindowsFS.Delete(strDEST_PATH)
                            glbl.gWindowsFS.Move(strFILE_PATH & ".TDLY", strDEST_PATH)
                        End If 'strFILE_PATH
                    Next rowFILE
                Next intLEN
            End Sub 'Move_Files
        End Class 'sFileMove

        Partial Class sUserBowl
            Public Function Apply(ur_filemove_cart As sFileMove) As enmUN.zreport_output
                Dim retKEY = enmUN.report_output
                Apply = retKEY
                Dim stpREPORT = Strapd()
                For Each rowFILE In ur_filemove_cart.SelAll
                    stpREPORT.dLine(Now.ToString("tt hh:mm:ss")).d(":").dS(rowFILE.v(enmFM.dest_file_path))
                Next rowFILE

                Me.SelKey(retKEY).v(enmUB.contents) = stpREPORT
            End Function 'Apply(ur_filemove_cart
        End Class 'sUserBowl
    End Class 'Have



    Partial Public Class Have
        Private Shared envWindowsCboard As glblWindowsCboard
        Private Shared envWindowsMsgBox As glblWindowsMsgBox
        Private Shared envWindowsFS As glblWindowsFS
        Private Shared tblFileMove As sFileMove
        Private Shared tblUserBowl As sUserBowl

        <System.Diagnostics.DebuggerHidden()>
        Private Shared Sub Connect()
            If Have.tblUserBowl Is Nothing Then
                Have.envWindowsCboard = New glblWindowsCboard
                Have.envWindowsMsgBox = New glblWindowsMsgBox
                Have.envWindowsFS = New glblWindowsFS
                Have.tblFileMove = New sFileMove
                Have.tblUserBowl = New sUserBowl
            End If 'sdaTCOL_NAME
        End Sub 'Connect
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsCboard() As glblWindowsCboard
            Call Have.Connect()
            WindowsCboard = Have.envWindowsCboard
        End Function

        Public Class glblWindowsCboard
            Public Function SetText(ur_text As String) As Integer
                SetText = Mx.glbl.gCboard.SetText(ur_text)
            End Function
        End Class 'glblWindowsCboard
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsMsgBox() As glblWindowsMsgBox
            Call Have.Connect()
            WindowsMsgBox = Have.envWindowsMsgBox
        End Function

        Public Class glblWindowsMsgBox
            Public Function GetResult(ur_message As String, ur_title As String, ur_style As MsgBoxStyle) As MsgBoxResult
                GetResult = Mx.glbl.gMsgBox.GetResult(ur_message, ur_style, ur_title)
            End Function
        End Class 'glblWindowsMsgBox
    End Class 'Have

    Partial Public Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function WindowsFS() As glblWindowsFS
            Call Have.Connect()
            WindowsFS = Have.envWindowsFS
        End Function

        Public Class glblWindowsFS
            Public Function GetFiles(ur_search_folder As String, ur_filespec As String, ur_recurse_option As System.IO.SearchOption) As String()
                GetFiles = Mx.glbl.gWindowsFS.GetFiles(ur_search_folder, ur_filespec, ur_recurse_option)
            End Function

            Public Function ReadAllText(ur_file_path As String) As String
                ReadAllText = Mx.glbl.gWindowsFS.ReadAllText(ur_file_path)
            End Function
        End Class 'glblWindowsFS
    End Class 'Have

    Public Class enmFM
        Inherits bitBASE
        Public Shared src_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
        Public Shared dest_file_path As enmFM = TRow(Of enmFM).glbl.NewBitBase()
    End Class

    Partial Class Have
        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function FileMove() As sFileMove
            Call Have.Connect()
            FileMove = Have.tblFileMove
        End Function

        Public Class rFileMove
            Inherits TRow(Of enmFM)

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmFM, ur_val As String) As rFileMove
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function
        End Class 'rFileMove

        Public Class sFileMove
            Private ttb As Objlist(Of rFileMove)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub New()
                Me.ttb = New Objlist(Of rFileMove)
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Sub DelAll()
                Me.ttb.Clear()
            End Sub

            <System.Diagnostics.DebuggerHidden()>
            Public Function Ins(ur_from As rFileMove) As rFileMove
                Ins = ur_from
                Dim ttbSEL = Me
                Me.ttb.Add(ur_from)
            End Function 'Ins

            Public ReadOnly Property SelAll() As Objlist(Of rFileMove)
                <System.Diagnostics.DebuggerHidden()>
                Get
                    SelAll = ttb
                End Get
            End Property 'SelAll

            <System.Diagnostics.DebuggerHidden()>
            Public Overloads Function ToString(ur_hdr As Boolean) As String
                Dim stpRET = Strapd() : For Each kvpREC In Me.ttb.kvp
                    stpRET.d(kvpREC.row.ToString((kvpREC.Indexb1 = 1) And ur_hdr))
                Next kvpREC : ToString = stpRET
            End Function 'ToString
            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sFileMove
    End Class 'Have

    Public Class enmUB
        Inherits bitBASE
        Public Shared bowl_name As enmUB = TRow(Of enmUB).glbl.NewBitBase()
        Public Shared contents As enmUB = TRow(Of enmUB).glbl.NewBitBase()
    End Class

    Public Class enmUN
        Inherits bitBASE
        Public Shared app_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_name As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared app_path As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_audit As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_orig As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared cmdline_table As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared in_subfolder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared from_messagebox As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared poll_folder As enmUN = TRow(Of enmUN).glbl.NewBitBase()
        Public Shared report_output As zreport_output = TRow(Of enmUN).glbl.Trbase(Of zreport_output).NewBitBase() : Public Class zreport_output : Inherits enmUN : End Class
        Public Shared uiform_title As enmUN = TRow(Of enmUN).glbl.NewBitBase()
    End Class

    Public Class enmUR
        Inherits bitBASE
        Public Shared Ok As enmUR = TRow(Of enmUR).glbl.NewBitBase()
        Public Shared Cancel As enmUR = TRow(Of enmUR).glbl.NewBitBase()
    End Class

    Partial Public Class Have
        Public Shared FirstConnect As Object
        Public Shared CmdLineText As String

        <System.Diagnostics.DebuggerHidden()>
        Public Shared Function UserBowl() As sUserBowl
            Dim bolFIRST_INIT = (Have.FirstConnect Is Nothing)
            Call Have.Connect()
            UserBowl = Have.tblUserBowl
            If bolFIRST_INIT Then
                Have.FirstConnect = "Done"
                Call Have.tblUserBowl.InsFrom_Application()
                'Have.tblUserBowl.InsKey(enmUN.cmdline_audit, "1")
                Call Have.tblUserBowl.Cboard_CmdlineAudit()
            End If
        End Function 'UserBowl

        Public Class rUserBowl
            Inherits TRow(Of enmUB)

            <System.Diagnostics.DebuggerHidden()>
            Public Function v_is(ur_enm As enmUB, ur_cmp As enmUR) As Boolean
                v_is = AreEqual(Me.v(ur_enm), ur_cmp.name)
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function vt(ur_enm As enmUB, ur_val As String) As rUserBowl
                vt = Me
                Me.v(ur_enm) = ur_val
            End Function

            Public Property Contents As String
                <System.Diagnostics.DebuggerHidden()>
                Get
                    Contents = Me.v(enmUB.contents)
                End Get
                <System.Diagnostics.DebuggerHidden()>
                Set(value As String)
                    Me.v(enmUB.contents) = value
                End Set
            End Property 'Contents
        End Class 'rUserBowl

        Public Class sUserBowl
            Inherits Mx.TablePKEnum(Of enmUB, enmUN, rUserBowl)

            <System.Diagnostics.DebuggerHidden()>
            Public Sub Cboard_CmdlineAudit()
                If HasText(Me.SelKey(enmUN.cmdline_audit).v(enmUB.contents)) Then
                    Dim strAUDIT = Me.ToString(True)
                    Dim enrUSER_INPUT = Have.WindowsMsgBox.GetResult(
                        ur_title:=Me.SelKey(enmUN.app_name).v(enmUB.contents),
                        ur_message:=strAUDIT,
                        ur_style:=MsgBoxStyle.OkCancel
                        )
                    If enrUSER_INPUT = MsgBoxResult.Ok Then
                        Have.WindowsCboard.SetText(strAUDIT)
                    End If
                End If
            End Sub 'Cboard_CmdlineAudit

            <System.Diagnostics.DebuggerHidden()>
            Public Function InsFrom_Application() As rUserBowl
                Dim ret = New rUserBowl
                InsFrom_Application = ret
                Me.SelKey(enmUN.app_name).Contents = Mx.FileNamed().d(Mx.Class1.SourcePath).FileGroup
                Me.SelKey(enmUN.app_path).Contents = Mx.Class1.SourcePath
                Me.SelKey(enmUN.app_folder).Contents = Mx.Class1.SourceFolder

                Dim arlCMD_RET = MxText.Cmdline_UB(Of enmUN, enmUB).CommandLine_UBParm(enmUB.bowl_name, enmUB.contents, Have.CmdLineText)
                Me.SelKey(enmUN.cmdline_orig).Contents = qs & Have.CmdLineText.Replace(qs, qs & qs) & qs
                Me.SelKey(enmUN.cmdline_table).Contents = qs & arlCMD_RET.ttbCMD_PARM.ToString(True).Replace(qs, qs & qs) & qs
                For Each rowFOUND In arlCMD_RET.ttbUB_PARM
                    Me.Sel(enmUB.bowl_name, rowFOUND.v(enmUB.bowl_name)).SelFirst.Contents = rowFOUND.v(enmUB.contents)
                Next
            End Function

            <System.Diagnostics.DebuggerHidden()>
            Public Function ToCbrd(ur_hdr As Boolean) As Integer
                ToCbrd = Mx.glbl.gCboard.SetText(Me.ToString(ur_hdr))
            End Function
        End Class 'sUserBowl
    End Class 'UB, UN
End Namespace 'Mx

View All Cards

$:/positivesigner/text-ref
<$list filter="[all[tiddlers]!tag[EXTLINK]!tag[IMG]!tag[INDEX]!tag[MCR]!tag[META]!has[draft.of]!is[image]!is[tag]!is[system]has[tags]!prefix[undefined]sort[title]]">
<hr>
<h2><$link to=<<currentTiddler>> /></h2>
{{||$:/core/ui/ViewTemplate/tags}}
<$transclude mode="block"/>
</$list>

View All Code

$:/positivesigner/text-ref
<$list variable=cur_card_pk filter="[!has[draft.of]!prefix[undefined]!prefix[$]] [prefix[$]!has[draft.of]has[tags]] +[sort[title]]">
<hr>
<h2><$link to=<<cur_card_pk>> /></h2>
<$list variable=cur_card_tags filter="[<cur_card_pk>tags[]]">
<<cur_card_tags>> 
</$list><!--cur_card_text-->
<$list variable=cur_card_text filter="[<cur_card_pk>get[text]]">
<$codeblock code=<<cur_card_text>> />
</$list><!--cur_card_text-->
</$list><!--cur_card_pk-->

WindowsCLI

DOC
<<glbl_article_list>>

WindowsCLI\Batch Replacement Parameters

WindowsCLI AssignVariable
"""
User Replacement Text = UrProgram

[Example.cmd file]
- SET CUR_DIR=%~dp0
- "%CUR_DIR%UrProgram.exe"

WindowsCLI\Command line hide Errors

WindowsCLI ErrorHandling
"""
[Windows CLI]
- [Turn off standard messages being echoed to the console]
- `@@ECHO OFF`

[https://docs.microsoft.com/en-us/troubleshoot/cpp/redirecting-error-command-prompt]
- To redirect the error message to NUL, use the following command:
"""

```
dir file.xxx 2> nul
```

"""
- You can print the errors and standard output to a single file by using the &1 command to redirect the output for STDERR to STDOUT and then sending the output from STDOUT to a file:
"""

```
dir file.xxx 1> output.msg 2>&1
```

WindowsCLI\Command list

WindowsCLI CodeLibrary
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands

"""

Prerequisites
The information that is contained in this topic applies to:Windows Server 2019

Windows Server (Semi-Annual Channel)

Windows Server 2016

Windows Server 2012 R2

Windows Server 2012

Windows Server 2008 R2

Windows Server 2008

Windows 10

Windows 8.1Command shell overview
The Command shell was the first shell built into Windows to automate routine tasks, like user account management or nightly backups, with batch (.bat) files. With Windows Script Host you could run more sophisticated scripts in the Command shell. For more information, see
cscript
or
wscript
. You can perform operations more efficiently by using scripts than you can by using the user interface. Scripts accept all Commands that are available at the command line.

Windows has two command shells: The Command shell and
PowerShell
. Each shell is a software program that provides direct communication between you and the operating system or application, providing an environment to automate IT operations.

PowerShell was designed to extend the capabilities of the Command shell to run PowerShell commands called cmdlets. Cmdlets are similar to Windows Commands but provide a more extensible scripting language. You can run Windows Commands and PowerShell cmdlets in Powershell, but the Command shell can only run Windows Commands and not PowerShell cmdlets.

For the most robust, up-to-date Windows automation, we recommend using PowerShell instead of Windows Commands or Windows Script Host for Windows automation.

Note

You can also download and install
PowerShell Core
, the open source version of PowerShell. Caution

Incorrectly editing the registry may severely damage your system. Before making the following changes to the registry, you should back up any valued data on the computer. Note

To enable or disable file and directory name completion in the Command shell on a computer or user logon session, run
regedit.exe
and set the following
reg_DWOrd value
:

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\completionChar\reg_DWOrd

To set the
reg_DWOrd
value, use the hexadecimal value of a control character for a particular function (for example,
0 9
is Tab and
0 08
is Backspace). User-specified settings take precedence over computer settings, and command-line options take precedence over registry settings.Command-line reference A-Z
To find information about a specific Windows Command, in the following A-Z menu, click the letter that the Command starts with, and then click the Command name.

A append
arp
assoc
at
atmadm
attrib
auditpol
autochk
autoconv
autofmt
B bcdboot
bcdedit
bdehdcfg
bitsadmin
bitsadmin addfile
bitsadmin addfileset
bitsadmin addfilewithranges
bitsadmin cancel
bitsadmin complete
bitsadmin create
bitsadmin getaclflags
bitsadmin getbytestotal
bitsadmin getbytestransferred
bitsadmin getcompletiontime
bitsadmin getcreationtime
bitsadmin getdescription
bitsadmin getdisplayname
bitsadmin geterror
bitsadmin geterrorcount
bitsadmin getfilestotal
bitsadmin getfilestransferred
bitsadmin getminretrydelay
bitsadmin getmodificationtime
bitsadmin getnoprogresstimeout
bitsadmin getnotifycmdline
bitsadmin getnotifyflags
bitsadmin getnotifyinterface
bitsadmin getowner
bitsadmin get priority
bitsadmin getproxybypasslist
bitsadmin getproxylist
bitsadmin getproxyusage
bitsadmin getreplydata
bitsadmin getreplyfilename
bitsadmin getreplyprogress
bitsadmin getstate
bitsadmin gettype
bitsadmin help
bitsadmin info
bitsadmin list
bitsadmin listfiles
bitsadmin monitor
bitsadmin nowrap
bitsadmin rawreturn
bitsadmin removecredentials
bitsadmin replaceremoteprefix
bitsadmin reset
bitsadmin resume
bitsadmin setaclflag
bitsadmin setcredentials
bitsadmin setdescription
bitsadmin setdisplayname
bitsadmin setminretrydelay
bitsadmin setnoprogresstimeout
bitsadmin setnotifycmdline
bitsadmin setnotifyflags
bitsadmin setpriority
bitsadmin setproxysettings
bitsadmin setreplyfilename
bitsadmin suspend
bitsadmin takeownership
bitsadmin Transfer
bitsadmin util
bitsadmin wrap bootcfg
bootcfg addsw
bootcfg copy
bootcfg dbg1394
bootcfg debug
  bootcfg default
bootcfg delete
bootcfg ems
bootcfg query
bootcfg raw
bootcfg rmsw
bootcfg timeout break
C cacls
call
cd
certreq
certutil
change
change logon
change port
change user chcp
chdir
chglogon
chgport
chgusr
chkdsk
chkntfs
choice
cipher
cleanmgr
clip
cls
Cmd
cmdkey
cmstp
color
comp
compact
convert
copy
cprofile
cscript
D date
dcgpofix
defrag
del
dfsrmig
diantz
dir
diskcomp
diskcopy
diskpart
diskperf
diskraid
diskshadow
dispdiag
dnscmd
doskey
driverquery
E echo
edit
endlocal
erase
eventcreate
eventquery
eventtriggers
evntcmd
exit
expand
extract
F fc
find
findstr
finger
flattemp
fondue
for
forfiles
format
freedisk
fsutil
fsutil 8dot3name
 fsutil behavior
 fsutil file
fsutil fsinfo
fsutil hardlink
fsutil objectid
fsutil quota
fsutil repair
fsutil reparsepoint
fsutil resource
fsutil sparse
fsutil tiering
fsutil transaction
fsutil usn
fsutil volume
fsutil wim ftp
ftype
fveupdate
G getmac
gettype
goto
gpfixup
gpresult
gpupdate
graftabl
H help
helpctr
hostname
I icacls
if
inuse
ipconfig
ipxroute
irftp
J jetpack
K klist
ksetup
ksetup:setrealm
ksetup:mapuser
ksetup:addkdc
ksetup:delkdc
ksetup:addkpasswd
ksetup:delkpasswd
ksetup:server
ksetup:setcomputerpassword
ksetup:removerealm
ksetup:domain
ksetup:changepassword
ksetup:listrealmflags
ksetup:setrealmflags
ksetup:addrealmflags
ksetup:delrealmflags
ksetup:dumpstate
ksetup:addhosttorealmmap
ksetup:delhosttorealmmap
ksetup:setenctypeattr
ksetup:getenctypeattr
ksetup:addenctypeattr
ksetup:delenctypeattr ktmutil
ktpass
L label
lodctr
logman
logman create
logman query
logman start &124; stop
logman delete
logman update
logman import &124; export logoff
lpq
lpr
M macfile
makecab
manage-bde
manage-bde: status
manage-bde: on
manage-bde: off
manage-bde: pause
manage-bde: resume
manage-bde: lock
manage-bde: unlock
manage-bde: autounlock
manage-bde: protectors
manage-bde: tpm
manage-bde: setidentifier
manage-bde: ForceRecovery
manage-bde: changepassword
manage-bde: changepin
manage-bde: changekey
manage-bde: KeyPackage
manage-bde: upgrade
manage-bde: WipeFreeSpace mapadmin
Md
mkdir
mklink
mmc
mode
more
mount
mountvol
move
mqbkup
mqsvc
mqtgsvc
msdt
msg
msiexec
msinfo32
mstsc
N nbtstat
netcfg
netsh
netstat
Net print
nfsadmin
nfsshare
nfsstat
nlbmgr
nslookup
nslookup exit command
nslookup finger command
nslookup help
nslookup ls
nslookup lserver
nslookup root
nslookup server
nslookup set
nslookup set all
nslookup set class
nslookup set d2
nslookup set debug
nslookup set domain
nslookup set port
nslookup set querytype
nslookup set recurse
nslookup set retry
nslookup set root
nslookup set search
nslookup set srchlist
nslookup set timeout
nslookup set type
nslookup set vc
nslookup view ntbackup
ntcmdprompt
ntfrsutl
O openfiles
P pagefileconfig
path
pathping
pause
pbadmin
pentnt
perfmon
ping
pnpunattend
pnputil
popd
PowerShell
PowerShell_ise
print
prncnfg
prndrvr
prnjobs
prnmngr
prnport
prnqctl
prompt
pubprn
pushd
pushprinterconnections
Q qappsrv
qprocess
query
quser
qwinsta
R rcp
rd
rdpsign
recover
reg
reg add
reg compare
reg copy
reg delete
reg export
reg import
reg load
reg query
reg restore
reg save
reg unload regini
regsvr32
relog
rem
ren
rename
repair-bde
replace
reset session
rexec
risetup
rmdir
robocopy
route_ws2008
rpcinfo
rpcping
rsh
rundll32
rwinsta
S schtasks
scwcmd
scwcmd: analyze
scwcmd: configure
scwcmd: register
scwcmd: rollback
 scwcmd: transform
 scwcmd: view
 

secedit
secedit:analyze
secedit:configure
secedit:export
secedit:generaterollback
secedit:import
secedit:validate serverceipoptin
Servermanagercmd
serverweroptin
set
setlocal
setx
sfc
shadow
shift
showmount
shutdown
sort
start
subst
sxstrace
sysocmgr
systeminfo
T takeown
tapicfg
taskkill
tasklist
tcmsetup
telnet
tftp
time
timeout
title
tlntadmn
tpmvscmgr
tracerpt
tracert
tree
tscon
tsdiscon
tsecimp
tskill
tsprof
type
typeperf
tzutil
U unlodctr
V ver
verifier
verify
vol
vssadmin
-W waitfor
wbadmin
wbadmin enable backup
wbadmin disable backup
wbadmin start backup
wbadmin stop job
wbadmin get versions
wbadmin get items
wbadmin start recovery
wbadmin get status
wbadmin get disks
wbadmin start systemstaterecovery
wbadmin start systemstatebackup
wbadmin delete systemstatebackup
wbadmin start sysrecovery
wbadmin restore catalog
wbadmin delete catalog wdsutil
wecutil
wevtutil
where
whoami
winnt
winnt32
winpop
winrs
wmic
wscript
X xcopy

WindowsCLI\Environment Variables

EnvironmentVariable WindowsCLI Extract
!! Windows CLI Environment Variable examples

<<ext "Windows Environment Variable List">>

* Environment variable %USERPROFILE%

User-replaced value = UrUserName

!! Show the Current Directory environment variable
* [Windows CLI]
* `ECHO %CD%`
* Press enter -> `C:\UrFolderPath\UrSubfolder`

!! Navigate to the C:\Users\UrUserName folder
* [Windows CLI]
* `cd %USERPROFILE%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName`

!! Navigate to the C:\Users\UrUserName\AppData\Local\Temp folder
* `cd %TEMP%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName\AppData\Local\Temp`

!! Navigate to the C:\Users\UrUserName\AppData\Roaming folder
* `cd %APPDATA%`
* Press enter
* `cd`
* Press enter -> `C:\Users\UrUserName\AppData\Roaming`

WindowsCLI\Unicode characters

WindowsCLI Unicode Text WindowsOS
!! Use the standard Windows ANSI Character input
<<ext "Windows Alt-Numpad Unicode">>
* Hold down Alt key, then type the Decimal sequence using only the 0-9 on the Numeric Keypad
* Note: This only works for the 255 characters in the current Windows code page

!! Enable Alt-Numeric Keypad input of Unicode Characters
* Start `RegEdit.exe`
* Navigate to`HKEY_CURRENT_USER\Control Panel\Input Method`
!!
* [New String Value]
* name = `EnableHexNumpad`
* value = `1`
!!
* [Start Menu]
* Reboot your computer
!!
* [In any Windows program]
* Turn on `Numlock`

* Hold down `Alt`-key, then type the Numeric Keypad Plus (+) key once
* Still holding down the `Alt`-key, type the hexadecimal sequence using only the letters A-F on the main keyboard and 0-9 on the Numeric Keypad
* Release the `Alt`-key -> Windows pastes the Unicode character in the current program window
* Note: This may not work for 5-digit hexadecimal codes like U+1F937

!! Use the FileFormat.Info tool Unicode Input

<<ext "FileFormat.Info UnicodeInput">>

[In any program]
* Hold down 'Alt'-key, then type the Numeric Keypad Plus (+) key -> Opens dialog box
* Note: The `U+` displayed in the window means "Enter a Unicode character number in hexadecimal format"
* Type in a hexadecimal number
* Press enter -or- Click button Send -> Closes window, types desired Unicode character in foreground window

<<ext "FileFormat.Info UnicodeInput.ZIP">>

* Note: This EXE program is able to be started from anywhere
* Note: Closing the window minimizes to the system tray as `blue circle with white lowercase letter i`

!! Display Unicode UTF-8 characters in Windows CLI

* [In some UrProgram.cmd file or Command Prompt window]
* First put the line: `@chcp 65001>nul`
* Stream UTF-8 characters from files to the Command Prompt window -> Unicode characters are shown correctly
* Note: If you do not change the code page, Unicode characters will be split into as High- and Low-ASCII characters from the current Windows code page

<<ext "WindowsCLI Unicode Support">>
* HEX input delivers a character on KeyUp of Alt; all the other ways to deliver a character happen on KeyDown; so many applications are not ready to see a character on KeyUp. (Only applicable to applications using Console-I/O API.)
* Conclusion: Many application would not react on HEX input events.
* Note: Unless your keyboard layout supports input of A LOT of characters without prefix keys, some buggy applications may skip characters when you Paste via Console’s UI
!!
* One should also keep in mind that the “alternative, ‘more capable’ consoles” for Windows are not consoles at all. They do not support Console-I/O APIs, so the programs which rely on these APIs to work would not function. (The programs which use only “File-I/O APIs to the console filehandles” would work fine, though.)
* Note: One example of such non-console is a part of MicroSoft’s Powershell. 

!! Change the default Codepage of Windows console
* [RegEdit.exe]
* Navigate to `HKEY_CURRENT_USER\Software\Microsoft\Command Processor`
!!
* [New String Value]
* Name = `Autorun`
* Value = `chcp 65001`
!!
* Actually, the trick is that the command prompt actually understands these non-english characters, just can't display them correctly
* Note: When I enter a path in the command prompt that contains some non-english chracters it is displayed as "?? ?????? ?????"
* Note:  When you submit your command (cd "??? ?????? ?????" in my case), everything is working as expected

!! <<ext "Windows Terminal Unicode Support">>
* Windows Terminal is a new, modern, fast, efficient, powerful, and productive terminal application for users of command-line tools and shells like Command Prompt, PowerShell, and WSL.

YouTube

DOC
<<glbl_article_list>>

YouTube\Captions text

YouTube ClosedCaptions Extract
!! Export closed captions text file from a YouTube video page
* Note: Android O/S will need to show the YouTube page as a Desktop Site
!!
* [Top-right icons]
* Click the three-dots menu, option Desktop site -> Reloads page
!!
* [Below video, Right-side icons]
* Click the three-dots menu, option Open Transcript -> Navigates page below video or right-side of video
* You can highlight the captions text and copy to the clipboard
* Note: You can paste the captions text into a document and save or print them

!! Find closed captions text file in YouTube video HTML content on Windows
* Type Ctrl-A to Select all text on the page
* Paste all text into a new text document
* At the top of the file, search down for "00:" to find the first line of the captions text
* Delete all text above this line
!!
* At the bottom of the file, search up for "00:" to find the last line of the captions text
* Delete all text below this line
* The remaining lines are the closed captions file

!! Find closed captions text file in YouTube video HTML content on Android O/S
* Search for "views" or [the video title] to find the end of the captions text

WindowsCLI\Batch Replacement Parameters

8th January 2021 at 8:15am
AssignVariable WindowsCLI

User Replacement Text = UrProgram

[Example.cmd file]
- SET CUR_DIR=%~dp0
- "%CUR_DIR%UrProgram.exe"

WindowsCLI\Command line hide Errors

8th January 2021 at 8:15am
ErrorHandling WindowsCLI

[Windows CLI]
- [Turn off standard messages being echoed to the console]
- @@ECHO OFF

[https://docs.microsoft.com/en-us/troubleshoot/cpp/redirecting-error-command-prompt]
- To redirect the error message to NUL, use the following command:

dir file.xxx 2> nul

- You can print the errors and standard output to a single file by using the &1 command to redirect the output for STDERR to STDOUT and then sending the output from STDOUT to a file:

dir file.xxx 1> output.msg 2>&1

WindowsCLI\Command list

8th January 2021 at 8:30am
CodeLibrary WindowsCLI

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands


Prerequisites
The information that is contained in this topic applies to:Windows Server 2019

Windows Server (Semi-Annual Channel)

Windows Server 2016

Windows Server 2012 R2

Windows Server 2012

Windows Server 2008 R2

Windows Server 2008

Windows 10

Windows 8.1Command shell overview
The Command shell was the first shell built into Windows to automate routine tasks, like user account management or nightly backups, with batch (.bat) files. With Windows Script Host you could run more sophisticated scripts in the Command shell. For more information, see
cscript
or
wscript
. You can perform operations more efficiently by using scripts than you can by using the user interface. Scripts accept all Commands that are available at the command line.

Windows has two command shells: The Command shell and
PowerShell
. Each shell is a software program that provides direct communication between you and the operating system or application, providing an environment to automate IT operations.

PowerShell was designed to extend the capabilities of the Command shell to run PowerShell commands called cmdlets. Cmdlets are similar to Windows Commands but provide a more extensible scripting language. You can run Windows Commands and PowerShell cmdlets in Powershell, but the Command shell can only run Windows Commands and not PowerShell cmdlets.

For the most robust, up-to-date Windows automation, we recommend using PowerShell instead of Windows Commands or Windows Script Host for Windows automation.

Note

You can also download and install
PowerShell Core
, the open source version of PowerShell. Caution

Incorrectly editing the registry may severely damage your system. Before making the following changes to the registry, you should back up any valued data on the computer. Note

To enable or disable file and directory name completion in the Command shell on a computer or user logon session, run
regedit.exe
and set the following
reg_DWOrd value
:

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\completionChar\reg_DWOrd

To set the
reg_DWOrd
value, use the hexadecimal value of a control character for a particular function (for example,
0 9
is Tab and
0 08
is Backspace). User-specified settings take precedence over computer settings, and command-line options take precedence over registry settings.Command-line reference A-Z
To find information about a specific Windows Command, in the following A-Z menu, click the letter that the Command starts with, and then click the Command name.

A append
arp
assoc
at
atmadm
attrib
auditpol
autochk
autoconv
autofmt
B bcdboot
bcdedit
bdehdcfg
bitsadmin
bitsadmin addfile
bitsadmin addfileset
bitsadmin addfilewithranges
bitsadmin cancel
bitsadmin complete
bitsadmin create
bitsadmin getaclflags
bitsadmin getbytestotal
bitsadmin getbytestransferred
bitsadmin getcompletiontime
bitsadmin getcreationtime
bitsadmin getdescription
bitsadmin getdisplayname
bitsadmin geterror
bitsadmin geterrorcount
bitsadmin getfilestotal
bitsadmin getfilestransferred
bitsadmin getminretrydelay
bitsadmin getmodificationtime
bitsadmin getnoprogresstimeout
bitsadmin getnotifycmdline
bitsadmin getnotifyflags
bitsadmin getnotifyinterface
bitsadmin getowner
bitsadmin get priority
bitsadmin getproxybypasslist
bitsadmin getproxylist
bitsadmin getproxyusage
bitsadmin getreplydata
bitsadmin getreplyfilename
bitsadmin getreplyprogress
bitsadmin getstate
bitsadmin gettype
bitsadmin help
bitsadmin info
bitsadmin list
bitsadmin listfiles
bitsadmin monitor
bitsadmin nowrap
bitsadmin rawreturn
bitsadmin removecredentials
bitsadmin replaceremoteprefix
bitsadmin reset
bitsadmin resume
bitsadmin setaclflag
bitsadmin setcredentials
bitsadmin setdescription
bitsadmin setdisplayname
bitsadmin setminretrydelay
bitsadmin setnoprogresstimeout
bitsadmin setnotifycmdline
bitsadmin setnotifyflags
bitsadmin setpriority
bitsadmin setproxysettings
bitsadmin setreplyfilename
bitsadmin suspend
bitsadmin takeownership
bitsadmin Transfer
bitsadmin util
bitsadmin wrap bootcfg
bootcfg addsw
bootcfg copy
bootcfg dbg1394
bootcfg debug
bootcfg default
bootcfg delete
bootcfg ems
bootcfg query
bootcfg raw
bootcfg rmsw
bootcfg timeout break
C cacls
call
cd
certreq
certutil
change
change logon
change port
change user chcp
chdir
chglogon
chgport
chgusr
chkdsk
chkntfs
choice
cipher
cleanmgr
clip
cls
Cmd
cmdkey
cmstp
color
comp
compact
convert
copy
cprofile
cscript
D date
dcgpofix
defrag
del
dfsrmig
diantz
dir
diskcomp
diskcopy
diskpart
diskperf
diskraid
diskshadow
dispdiag
dnscmd
doskey
driverquery
E echo
edit
endlocal
erase
eventcreate
eventquery
eventtriggers
evntcmd
exit
expand
extract
F fc
find
findstr
finger
flattemp
fondue
for
forfiles
format
freedisk
fsutil
fsutil 8dot3name
fsutil behavior
fsutil file
fsutil fsinfo
fsutil hardlink
fsutil objectid
fsutil quota
fsutil repair
fsutil reparsepoint
fsutil resource
fsutil sparse
fsutil tiering
fsutil transaction
fsutil usn
fsutil volume
fsutil wim ftp
ftype
fveupdate
G getmac
gettype
goto
gpfixup
gpresult
gpupdate
graftabl
H help
helpctr
hostname
I icacls
if
inuse
ipconfig
ipxroute
irftp
J jetpack
K klist
ksetup
ksetup:setrealm
ksetup:mapuser
ksetup:addkdc
ksetup:delkdc
ksetup:addkpasswd
ksetup:delkpasswd
ksetup:server
ksetup:setcomputerpassword
ksetup:removerealm
ksetup:domain
ksetup:changepassword
ksetup:listrealmflags
ksetup:setrealmflags
ksetup:addrealmflags
ksetup:delrealmflags
ksetup:dumpstate
ksetup:addhosttorealmmap
ksetup:delhosttorealmmap
ksetup:setenctypeattr
ksetup:getenctypeattr
ksetup:addenctypeattr
ksetup:delenctypeattr ktmutil
ktpass
L label
lodctr
logman
logman create
logman query
logman start &124; stop
logman delete
logman update
logman import &124; export logoff
lpq
lpr
M macfile
makecab
manage-bde
manage-bde: status
manage-bde: on
manage-bde: off
manage-bde: pause
manage-bde: resume
manage-bde: lock
manage-bde: unlock
manage-bde: autounlock
manage-bde: protectors
manage-bde: tpm
manage-bde: setidentifier
manage-bde: ForceRecovery
manage-bde: changepassword
manage-bde: changepin
manage-bde: changekey
manage-bde: KeyPackage
manage-bde: upgrade
manage-bde: WipeFreeSpace mapadmin
Md
mkdir
mklink
mmc
mode
more
mount
mountvol
move
mqbkup
mqsvc
mqtgsvc
msdt
msg
msiexec
msinfo32
mstsc
N nbtstat
netcfg
netsh
netstat
Net print
nfsadmin
nfsshare
nfsstat
nlbmgr
nslookup
nslookup exit command
nslookup finger command
nslookup help
nslookup ls
nslookup lserver
nslookup root
nslookup server
nslookup set
nslookup set all
nslookup set class
nslookup set d2
nslookup set debug
nslookup set domain
nslookup set port
nslookup set querytype
nslookup set recurse
nslookup set retry
nslookup set root
nslookup set search
nslookup set srchlist
nslookup set timeout
nslookup set type
nslookup set vc
nslookup view ntbackup
ntcmdprompt
ntfrsutl
O openfiles
P pagefileconfig
path
pathping
pause
pbadmin
pentnt
perfmon
ping
pnpunattend
pnputil
popd
PowerShell
PowerShell_ise
print
prncnfg
prndrvr
prnjobs
prnmngr
prnport
prnqctl
prompt
pubprn
pushd
pushprinterconnections
Q qappsrv
qprocess
query
quser
qwinsta
R rcp
rd
rdpsign
recover
reg
reg add
reg compare
reg copy
reg delete
reg export
reg import
reg load
reg query
reg restore
reg save
reg unload regini
regsvr32
relog
rem
ren
rename
repair-bde
replace
reset session
rexec
risetup
rmdir
robocopy
route_ws2008
rpcinfo
rpcping
rsh
rundll32
rwinsta
S schtasks
scwcmd
scwcmd: analyze
scwcmd: configure
scwcmd: register
scwcmd: rollback
scwcmd: transform
scwcmd: view


secedit
secedit:analyze
secedit:configure
secedit:export
secedit:generaterollback
secedit:import
secedit:validate serverceipoptin
Servermanagercmd
serverweroptin
set
setlocal
setx
sfc
shadow
shift
showmount
shutdown
sort
start
subst
sxstrace
sysocmgr
systeminfo
T takeown
tapicfg
taskkill
tasklist
tcmsetup
telnet
tftp
time
timeout
title
tlntadmn
tpmvscmgr
tracerpt
tracert
tree
tscon
tsdiscon
tsecimp
tskill
tsprof
type
typeperf
tzutil
U unlodctr
V ver
verifier
verify
vol
vssadmin
-W waitfor
wbadmin
wbadmin enable backup
wbadmin disable backup
wbadmin start backup
wbadmin stop job
wbadmin get versions
wbadmin get items
wbadmin start recovery
wbadmin get status
wbadmin get disks
wbadmin start systemstaterecovery
wbadmin start systemstatebackup
wbadmin delete systemstatebackup
wbadmin start sysrecovery
wbadmin restore catalog
wbadmin delete catalog wdsutil
wecutil
wevtutil
where
whoami
winnt
winnt32
winpop
winrs
wmic
wscript
X xcopy

WindowsCLI\Environment Variables

8th January 2021 at 8:13am
EnvironmentVariable Extract WindowsCLI

Windows CLI Environment Variable examples

Windows Environment Variable List

->

  • Environment variable %USERPROFILE%

User-replaced value = UrUserName

Show the Current Directory environment variable

  • [Windows CLI]
  • ECHO %CD%
  • Press enter -> C:\UrFolderPath\UrSubfolder

Navigate to the C:\Users\UrUserName folder

  • [Windows CLI]
  • cd %USERPROFILE%
  • Press enter
  • cd
  • Press enter -> C:\Users\UrUserName

Navigate to the C:\Users\UrUserName\AppData\Local\Temp folder

  • cd %TEMP%
  • Press enter
  • cd
  • Press enter -> C:\Users\UrUserName\AppData\Local\Temp

Navigate to the C:\Users\UrUserName\AppData\Roaming folder

  • cd %APPDATA%
  • Press enter
  • cd
  • Press enter -> C:\Users\UrUserName\AppData\Roaming

WindowsCLI\Unicode characters

8th January 2021 at 10:53am
Text Unicode WindowsCLI WindowsOS

Use the standard Windows ANSI Character input

Windows Alt-Numpad Unicode

->

  • Hold down Alt key, then type the Decimal sequence using only the 0-9 on the Numeric Keypad
  • Note: This only works for the 255 characters in the current Windows code page

Enable Alt-Numeric Keypad input of Unicode Characters

  • Start RegEdit.exe
  • Navigate toHKEY_CURRENT_USER\Control Panel\Input Method

  • [New String Value]
  • name = EnableHexNumpad
  • value = 1

  • [Start Menu]
  • Reboot your computer

  • [In any Windows program]
  • Turn on Numlock
  • Hold down Alt-key, then type the Numeric Keypad Plus (+) key once
  • Still holding down the Alt-key, type the hexadecimal sequence using only the letters A-F on the main keyboard and 0-9 on the Numeric Keypad
  • Release the Alt-key -> Windows pastes the Unicode character in the current program window
  • Note: This may not work for 5-digit hexadecimal codes like U+1F937

Use the FileFormat.Info tool Unicode Input

FileFormat.Info UnicodeInput

->

[In any program] * Hold down 'Alt'-key, then type the Numeric Keypad Plus (+) key -> Opens dialog box * Note: The U+ displayed in the window means "Enter a Unicode character number in hexadecimal format" * Type in a hexadecimal number * Press enter -or- Click button Send -> Closes window, types desired Unicode character in foreground window

FileFormat.Info UnicodeInput.ZIP

->

  • Note: This EXE program is able to be started from anywhere
  • Note: Closing the window minimizes to the system tray as blue circle with white lowercase letter i

Display Unicode UTF-8 characters in Windows CLI

  • [In some UrProgram.cmd file or Command Prompt window]
  • First put the line: @chcp 65001>nul
  • Stream UTF-8 characters from files to the Command Prompt window -> Unicode characters are shown correctly
  • Note: If you do not change the code page, Unicode characters will be split into as High- and Low-ASCII characters from the current Windows code page

WindowsCLI Unicode Support

->

  • HEX input delivers a character on KeyUp of Alt; all the other ways to deliver a character happen on KeyDown; so many applications are not ready to see a character on KeyUp. (Only applicable to applications using Console-I/O API.)
  • Conclusion: Many application would not react on HEX input events.
  • Note: Unless your keyboard layout supports input of A LOT of characters without prefix keys, some buggy applications may skip characters when you Paste via Console’s UI

  • One should also keep in mind that the “alternative, ‘more capable’ consoles” for Windows are not consoles at all. They do not support Console-I/O APIs, so the programs which rely on these APIs to work would not function. (The programs which use only “File-I/O APIs to the console filehandles” would work fine, though.)
  • Note: One example of such non-console is a part of MicroSoft’s Powershell.

Change the default Codepage of Windows console

  • [RegEdit.exe]
  • Navigate to HKEY_CURRENT_USER\Software\Microsoft\Command Processor

  • [New String Value]
  • Name = Autorun
  • Value = chcp 65001

  • Actually, the trick is that the command prompt actually understands these non-english characters, just can't display them correctly
  • Note: When I enter a path in the command prompt that contains some non-english chracters it is displayed as "?? ?????? ?????"
  • Note: When you submit your command (cd "??? ?????? ?????" in my case), everything is working as expected

Windows Terminal Unicode Support
->

  • Windows Terminal is a new, modern, fast, efficient, powerful, and productive terminal application for users of command-line tools and shells like Command Prompt, PowerShell, and WSL.

YouTube\Captions text

8th January 2021 at 7:37am
ClosedCaptions Extract YouTube

Export closed captions text file from a YouTube video page

  • Note: Android O/S will need to show the YouTube page as a Desktop Site

  • [Top-right icons]
  • Click the three-dots menu, option Desktop site -> Reloads page

  • [Below video, Right-side icons]
  • Click the three-dots menu, option Open Transcript -> Navigates page below video or right-side of video
  • You can highlight the captions text and copy to the clipboard
  • Note: You can paste the captions text into a document and save or print them

Find closed captions text file in YouTube video HTML content on Windows

  • Type Ctrl-A to Select all text on the page
  • Paste all text into a new text document
  • At the top of the file, search down for "00:" to find the first line of the captions text
  • Delete all text above this line

  • At the bottom of the file, search up for "00:" to find the last line of the captions text
  • Delete all text below this line
  • The remaining lines are the closed captions file

Find closed captions text file in YouTube video HTML content on Android O/S

  • Search for "views" or [the video title] to find the end of the captions text